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 669 2003-11-23 14:04:20Z edwin $
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"
58 #undef DEBUG /*define DEBUG 1*/
60 builtin_descriptor builtin_desc[] = {
61 {(functionptr) builtin_instanceof, "instanceof"},
62 {(functionptr) builtin_checkcast, "checkcast"},
63 {(functionptr) asm_builtin_checkcast, "checkcast"},
64 {(functionptr) builtin_arrayinstanceof, "arrayinstanceof"},
66 {(functionptr) asm_builtin_arrayinstanceof,"arrayinstanceof"},
68 {(functionptr) builtin_checkarraycast, "checkarraycast"},
69 {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
70 {(functionptr) asm_builtin_aastore, "aastore"},
71 {(functionptr) builtin_new, "new"},
72 {(functionptr) builtin_newarray, "newarray"},
73 {(functionptr) builtin_anewarray, "anewarray"},
76 * have 2 parameters (needs stack manipulation)
78 {(functionptr) asm_builtin_newarray, "newarray"},
80 {(functionptr) builtin_newarray_boolean, "newarray_boolean"},
81 {(functionptr) builtin_newarray_char, "newarray_char"},
82 {(functionptr) builtin_newarray_float, "newarray_float"},
83 {(functionptr) builtin_newarray_double, "newarray_double"},
84 {(functionptr) builtin_newarray_byte, "newarray_byte"},
85 {(functionptr) builtin_newarray_short, "newarray_short"},
86 {(functionptr) builtin_newarray_int, "newarray_int"},
87 {(functionptr) builtin_newarray_long, "newarray_long"},
88 {(functionptr) builtin_displaymethodstart, "displaymethodstart"},
89 {(functionptr) builtin_displaymethodstop, "displaymethodstop"},
90 {(functionptr) builtin_monitorenter, "monitorenter"},
91 {(functionptr) asm_builtin_monitorenter, "monitorenter"},
92 {(functionptr) builtin_monitorexit, "monitorexit"},
93 {(functionptr) asm_builtin_monitorexit, "monitorexit"},
95 {(functionptr) builtin_idiv, "idiv"},
96 {(functionptr) asm_builtin_idiv, "idiv"},
97 {(functionptr) builtin_irem, "irem"},
98 {(functionptr) asm_builtin_irem, "irem"},
100 {(functionptr) builtin_ladd, "ladd"},
101 {(functionptr) builtin_lsub, "lsub"},
102 {(functionptr) builtin_lmul, "lmul"},
103 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
104 {(functionptr) builtin_ldiv, "ldiv"},
105 {(functionptr) asm_builtin_ldiv, "ldiv"},
106 {(functionptr) builtin_lrem, "lrem"},
107 {(functionptr) asm_builtin_lrem, "lrem"},
109 {(functionptr) builtin_lshl, "lshl"},
110 {(functionptr) builtin_lshr, "lshr"},
111 {(functionptr) builtin_lushr, "lushr"},
112 {(functionptr) builtin_land, "land"},
113 {(functionptr) builtin_lor, "lor"},
114 {(functionptr) builtin_lxor, "lxor"},
115 {(functionptr) builtin_lneg, "lneg"},
116 {(functionptr) builtin_lcmp, "lcmp"},
117 {(functionptr) builtin_fadd, "fadd"},
118 {(functionptr) builtin_fsub, "fsub"},
119 {(functionptr) builtin_fmul, "fmul"},
120 {(functionptr) builtin_fdiv, "fdiv"},
121 {(functionptr) builtin_frem, "frem"},
122 {(functionptr) builtin_fneg, "fneg"},
123 {(functionptr) builtin_fcmpl, "fcmpl"},
124 {(functionptr) builtin_fcmpg, "fcmpg"},
125 {(functionptr) builtin_dadd, "dadd"},
126 {(functionptr) builtin_dsub, "dsub"},
127 {(functionptr) builtin_dmul, "dmul"},
128 {(functionptr) builtin_ddiv, "ddiv"},
129 {(functionptr) builtin_drem, "drem"},
130 {(functionptr) builtin_dneg, "dneg"},
131 {(functionptr) builtin_dcmpl, "dcmpl"},
132 {(functionptr) builtin_dcmpg, "dcmpg"},
133 {(functionptr) builtin_i2l, "i2l"},
134 {(functionptr) builtin_i2f, "i2f"},
135 {(functionptr) builtin_i2d, "i2d"},
136 {(functionptr) builtin_l2i, "l2i"},
137 {(functionptr) builtin_l2f, "l2f"},
138 {(functionptr) builtin_l2d, "l2d"},
139 {(functionptr) builtin_f2i, "f2i"},
140 {(functionptr) builtin_f2l, "f2l"},
141 {(functionptr) builtin_f2d, "f2d"},
142 {(functionptr) builtin_d2i, "d2i"},
143 {(functionptr) builtin_d2l, "d2l"},
144 #if defined(__I386__)
145 {(functionptr) asm_builtin_f2i, "f2i"},
146 {(functionptr) asm_builtin_f2l, "f2l"},
147 {(functionptr) asm_builtin_d2i, "d2i"},
148 {(functionptr) asm_builtin_d2l, "d2l"},
150 {(functionptr) builtin_d2f, "d2f"},
151 {(functionptr) NULL, "unknown"}
155 /*****************************************************************************
157 *****************************************************************************/
161 /*************** internal function: builtin_isanysubclass *********************
163 Checks a subclass relation between two classes. Implemented interfaces
164 are interpreted as super classes.
165 Return value: 1 ... sub is subclass of super
168 *****************************************************************************/
170 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
173 if (super->flags & ACC_INTERFACE)
174 return (sub->vftbl->interfacetablelength > super->index) &&
175 (sub->vftbl->interfacetable[-super->index] != NULL);
188 for (tmp=sub;tmp!=0;tmp=tmp->super) {
190 utf_display(tmp->name);
194 for (tmp=super;tmp!=0;tmp=tmp->super) {
196 utf_display(tmp->name);
201 printf("sub->vftbl->baseval %d, super->vftbl->baseval %d\n diff %d, super->vftbl->diffval %d\n",
202 sub->vftbl->baseval, super->vftbl->baseval, (unsigned)(sub->vftbl->baseval - super->vftbl->baseval),
203 super->vftbl->diffval); */
205 return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
206 (unsigned) (super->vftbl->diffval);
209 /* XXX inline this? */
210 s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super)
214 if ((base = super->baseval) <= 0)
215 /* super is an interface */
216 return (sub->interfacetablelength > -base) &&
217 (sub->interfacetable[base] != NULL);
218 return (unsigned) (sub->baseval - base)
219 <= (unsigned) (super->diffval);
223 /****************** function: builtin_instanceof *****************************
225 Checks if an object is an instance of some given class (or subclass of
226 that class). If class is an interface, checks if the interface is
228 Return value: 1 ... obj is an instance of class or implements the interface
229 0 ... otherwise or if obj == NULL
231 *****************************************************************************/
233 /* XXX should use vftbl */
234 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
237 log_text ("builtin_instanceof called");
240 return builtin_isanysubclass (obj->vftbl->class, class);
245 /**************** function: builtin_checkcast *******************************
247 The same as builtin_instanceof except that 1 is returned when
250 ****************************************************************************/
252 /* XXX should use vftbl */
253 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
256 log_text("builtin_checkcast called");
261 if (builtin_isanysubclass(obj->vftbl->class, class))
265 printf("#### checkcast failed ");
266 utf_display(obj->vftbl->class->name);
268 utf_display(class->name);
276 /*********** internal function: builtin_descriptorscompatible ******************
278 Checks if two array type descriptors are assignment compatible
279 Return value: 1 ... target = desc is possible
282 ******************************************************************************/
284 /* XXX inline this? */
285 static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target)
287 if (desc==target) return 1;
288 if (desc->arraytype != target->arraytype) return 0;
289 if (desc->arraytype != ARRAYTYPE_OBJECT) return 1;
291 /* {both arrays are arrays of references} */
292 if (desc->dimension == target->dimension)
293 return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
294 if (desc->dimension < target->dimension) return 0;
296 /* {desc has higher dimension than target} */
297 return builtin_isanysubclass_vftbl(pseudo_class_Arraystub_vftbl,target->elementvftbl);
300 /******************** function: builtin_checkarraycast ***********************
302 Checks if an object is really a subtype of the requested array type.
303 The object has to be an array to begin with. For simple arrays (int, short,
304 double, etc.) the types have to match exactly.
305 For arrays of objects, the type of elements in the array has to be a
306 subtype (or the same type) of the requested element type. For arrays of
307 arrays (which in turn can again be arrays of arrays), the types at the
308 lowest level have to satisfy the corresponding sub class relation.
310 Return value: 1 ... cast is possible
313 ATTENTION: a cast with a NULL pointer is always possible.
315 *****************************************************************************/
317 s4 builtin_checkarraycast(java_objectheader *o,arraydescriptor *target)
319 arraydescriptor *desc;
322 if ((desc = o->vftbl->arraydesc) == NULL) return 0;
324 return builtin_descriptorscompatible(desc,target);
327 s4 builtin_arrayinstanceof(java_objectheader *obj,arraydescriptor *desc)
330 return builtin_checkarraycast (obj, desc);
333 /************************** exception functions *******************************
335 ******************************************************************************/
337 java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr)
340 sprintf(logtext, "Builtin exception thrown: ");
341 if (local_exceptionptr)
342 utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
344 sprintf(logtext+strlen(logtext),"%s","Error: <Nullpointer instead of exception>");
345 if (!proto_java_lang_ClassCastException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ClassCastException==0");
346 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
347 if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
348 if (!proto_java_lang_ArrayIndexOutOfBoundsException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
349 if (!proto_java_lang_NegativeArraySizeException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NegativeArraySizeException==0");
350 if (!proto_java_lang_OutOfMemoryError) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_OutOfMemoryError==0");
351 if (!proto_java_lang_ArithmeticException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArithmeticException==0");
352 if (!proto_java_lang_ArrayStoreException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayStoreException==0");
353 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
354 if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
358 exceptionptr = local_exceptionptr;
359 return local_exceptionptr;
363 /******************* function: builtin_canstore *******************************
365 Checks, if an object can be stored in an array.
366 Return value: 1 ... possible
369 ******************************************************************************/
371 s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
373 arraydescriptor *desc;
374 arraydescriptor *valuedesc;
375 vftbl *componentvftbl;
382 /* The following is guaranteed (by verifier checks):
384 * *) a->...vftbl->arraydesc != NULL
385 * *) a->...vftbl->arraydesc->componentvftbl != NULL
386 * *) o->vftbl is not an interface vftbl
389 desc = a->header.objheader.vftbl->arraydesc;
390 componentvftbl = desc->componentvftbl;
391 valuevftbl = o->vftbl;
393 if ((dim_m1 = desc->dimension - 1) == 0) {
394 /* {a is a one-dimensional array} */
395 /* {a is an array of references} */
397 if (valuevftbl == componentvftbl)
400 if ((base = componentvftbl->baseval) <= 0)
401 /* an array of interface references */
402 return (valuevftbl->interfacetablelength > -base &&
403 valuevftbl->interfacetable[base] != NULL);
405 return (unsigned)(valuevftbl->baseval - base)
406 <= (unsigned)(componentvftbl->diffval);
408 /* {a has dimension > 1} */
409 /* {componentvftbl->arraydesc != NULL} */
411 /* check if o is an array */
412 if ((valuedesc = valuevftbl->arraydesc) == NULL)
414 /* {o is an array} */
416 return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
419 /* This is an optimized version where a is guaranteed to be one-dimensional */
420 s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
422 arraydescriptor *desc;
429 /* The following is guaranteed (by verifier checks):
431 * *) a->...vftbl->arraydesc != NULL
432 * *) a->...vftbl->arraydesc->elementvftbl != NULL
433 * *) a->...vftbl->arraydesc->dimension == 1
434 * *) o->vftbl is not an interface vftbl
437 desc = a->header.objheader.vftbl->arraydesc;
438 elementvftbl = desc->elementvftbl;
439 valuevftbl = o->vftbl;
441 /* {a is a one-dimensional array} */
443 if (valuevftbl == elementvftbl)
446 if ((base = elementvftbl->baseval) <= 0)
447 /* an array of interface references */
448 return (valuevftbl->interfacetablelength > -base &&
449 valuevftbl->interfacetable[base] != NULL);
451 return (unsigned)(valuevftbl->baseval - base)
452 <= (unsigned)(elementvftbl->diffval);
455 /* This is an optimized version where a is guaranteed to be a
456 * one-dimensional array of a class type */
457 /* XXX this could be inlined by the code generator */
458 s4 builtin_canstore_onedim_class (java_objectarray *a, java_objectheader *o)
465 /* The following is guaranteed (by verifier checks):
467 * *) a->...vftbl->arraydesc != NULL
468 * *) a->...vftbl->arraydesc->elementvftbl != NULL
469 * *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
470 * *) a->...vftbl->arraydesc->dimension == 1
471 * *) o->vftbl is not an interface vftbl
474 elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
475 valuevftbl = o->vftbl;
477 /* {a is a one-dimensional array} */
479 if (valuevftbl == elementvftbl)
482 return (unsigned)(valuevftbl->baseval - elementvftbl->baseval)
483 <= (unsigned)(elementvftbl->diffval);
487 /******************** Function: builtin_new **********************************
489 Creates a new instance of class c on the heap.
490 Return value: pointer to the object or NULL if no memory is
493 *****************************************************************************/
496 #define align_size(size) ((size + ((1 << ALIGNMENT) - 1)) & ~((1 << ALIGNMENT) - 1))
498 java_objectheader *builtin_new(classinfo *c)
500 java_objectheader *o;
504 #ifdef SIZE_FROM_CLASSINFO
505 c->alignedsize = align_size(c->instancesize);
506 o = heap_allocate(c->alignedsize, true, c->finalizer);
508 o = heap_allocate(c->instancesize, true, c->finalizer);
512 memset(o, 0, c->instancesize);
519 /********************** Function: builtin_newarray **************************
521 Creates an array with the given vftbl on the heap.
523 Return value: pointer to the array or NULL if no memory is available
525 CAUTION: The given vftbl must be the vftbl of the *array* class,
526 not of the element class.
528 *****************************************************************************/
530 java_arrayheader *builtin_newarray(s4 size,vftbl *arrayvftbl)
533 arraydescriptor *desc = arrayvftbl->arraydesc;
534 s4 dataoffset = desc->dataoffset;
535 s4 componentsize = desc->componentsize;
537 #ifdef SIZE_FROM_CLASSINFO
538 s4 actualsize = align_size(dataoffset + size * componentsize);
540 s4 actualsize = dataoffset + size * componentsize;
542 a = (java_arrayheader *)
543 heap_allocate(actualsize,
544 (desc->arraytype == ARRAYTYPE_OBJECT),
548 memset(a,0,actualsize);
550 a->objheader.vftbl = arrayvftbl;
552 #ifdef SIZE_FROM_CLASSINFO
553 a->alignedsize = actualsize;
558 /********************** Function: builtin_anewarray *************************
560 Creates an array of references to the given class type on the heap.
562 Return value: pointer to the array or NULL if no memory is available
564 XXX This function does not do The Right Thing, because it uses a
565 classinfo pointer at runtime. builtin_newarray should be used
568 *****************************************************************************/
571 builtin_anewarray(s4 size,classinfo *component)
573 return (java_objectarray*) builtin_newarray(size,class_array_of(component)->vftbl);
576 /******************** Function: builtin_newarray_int ***********************
578 Creates an array of 32 bit Integers on the heap.
580 Return value: pointer to the array or NULL if no memory is available
582 *****************************************************************************/
584 java_intarray *builtin_newarray_int (s4 size)
586 return (java_intarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
589 /******************** Function: builtin_newarray_long ***********************
591 Creates an array of 64 bit Integers on the heap.
593 Return value: pointer to the array or NULL if no memory is available
595 *****************************************************************************/
597 java_longarray *builtin_newarray_long (s4 size)
599 return (java_longarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
602 /******************** function: builtin_newarray_float ***********************
604 Creates an array of 32 bit IEEE floats on the heap.
606 Return value: pointer to the array or NULL if no memory is available
608 *****************************************************************************/
610 java_floatarray *builtin_newarray_float (s4 size)
612 return (java_floatarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
615 /******************** function: builtin_newarray_double ***********************
617 Creates an array of 64 bit IEEE floats on the heap.
619 Return value: pointer to the array or NULL if no memory is available
621 *****************************************************************************/
623 java_doublearray *builtin_newarray_double (s4 size)
625 return (java_doublearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
628 /******************** function: builtin_newarray_byte ***********************
630 Creates an array of 8 bit Integers on the heap.
632 Return value: pointer to the array or NULL if no memory is available
634 *****************************************************************************/
636 java_bytearray *builtin_newarray_byte (s4 size)
638 return (java_bytearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
641 /******************** function: builtin_newarray_char ************************
643 Creates an array of characters on the heap.
645 Return value: pointer to the array or NULL if no memory is available
647 *****************************************************************************/
649 java_chararray *builtin_newarray_char (s4 size)
651 return (java_chararray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
654 /******************** function: builtin_newarray_short ***********************
656 Creates an array of 16 bit Integers on the heap.
658 Return value: pointer to the array or NULL if no memory is available
660 *****************************************************************************/
662 java_shortarray *builtin_newarray_short (s4 size)
664 return (java_shortarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
667 /******************** function: builtin_newarray_boolean ************************
669 Creates an array of bytes on the heap. The array is designated as an array
670 of booleans (important for casts)
672 Return value: pointer to the array or NULL if no memory is available
674 *****************************************************************************/
676 java_booleanarray *builtin_newarray_boolean (s4 size)
678 return (java_booleanarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
681 /**************** function: builtin_nmultianewarray ***************************
683 Creates a multi-dimensional array on the heap. The dimensions are passed in
687 n............number of dimensions to create
688 arrayvftbl...vftbl of the array class
689 dims.........array containing the size of each dimension to create
691 Return value: pointer to the array or NULL if no memory is available
693 ******************************************************************************/
695 java_arrayheader *builtin_nmultianewarray (int n,
696 vftbl *arrayvftbl, long *dims)
700 vftbl *componentvftbl;
702 /* create this dimension */
703 size = (int) dims[0];
704 a = builtin_newarray(size,arrayvftbl);
707 /* if this is the last dimension return */
710 /* get the vftbl of the components to create */
711 componentvftbl = arrayvftbl->arraydesc->componentvftbl;
712 if (!componentvftbl) /* XXX the verifier could check this */
713 panic ("multianewarray with too many dimensions");
715 /* create the component arrays */
716 for (i = 0; i < size; i++) {
717 java_arrayheader *ea =
718 builtin_nmultianewarray(n,componentvftbl,dims+1);
719 if (!ea) return NULL;
720 ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
726 /*****************************************************************************
729 Various functions for printing a message at method entry or exit (for
732 *****************************************************************************/
737 java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
738 methodinfo *method, int *pos,
744 if (verbose || runverbose) {
745 printf("Exception ");
747 utf_display (exceptionptr->vftbl->class->name);
750 printf("Error: <Nullpointer instead of exception>");
751 if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
752 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
753 if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
754 if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
755 if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
756 if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
757 if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
758 if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
759 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
760 if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
763 printf(" thrown in ");
765 utf_display (method->class->name);
767 utf_display (method->name);
768 if (method->flags & ACC_SYNCHRONIZED)
772 printf("(%p) at position %p\n", method->entrypoint, pos);
775 printf("call_java_method\n");
782 #ifdef TRACE_ARGS_NUM
783 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
784 #if TRACE_ARGS_NUM > 6
791 for (i = 0; i < methodindent; i++)
793 sprintf(logtext + methodindent, "called: ");
794 utf_sprint(logtext + strlen(logtext), method->class->name);
795 sprintf(logtext + strlen(logtext), ".");
796 utf_sprint(logtext + strlen(logtext), method->name);
797 utf_sprint(logtext + strlen(logtext), method->descriptor);
798 sprintf(logtext + strlen(logtext), "(");
800 switch (method->paramcount) {
804 #if defined(__I386__)
806 sprintf(logtext+strlen(logtext), "%llx", a0);
810 sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1);
814 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2);
818 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx",
823 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx",
828 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx",
829 a0, a1, a2, a3, a4, a5);
832 #if TRACE_ARGS_NUM > 6
834 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx",
835 a0, a1, a2, a3, a4, a5, a6);
839 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx",
840 a0, a1, a2, a3, a4, a5, a6, a7);
844 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
845 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
849 sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)",
850 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
855 sprintf(logtext+strlen(logtext), "%lx", a0);
859 sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1);
863 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2);
867 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx",
872 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx",
877 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx",
878 a0, a1, a2, a3, a4, a5);
881 #if TRACE_ARGS_NUM > 6
883 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx",
884 a0, a1, a2, a3, a4, a5, a6);
888 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx",
889 a0, a1, a2, a3, a4, a5, a6, a7);
893 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
894 a0, a1, a2, a3, a4, a5, a6, a7, method->paramcount - 8);
898 sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)",
899 a0, a1, a2, a3, a4, a5, method->paramcount - 6);
904 sprintf (logtext+strlen(logtext), ")");
912 void builtin_displaymethodstart(methodinfo *method)
914 sprintf(logtext, " ");
915 sprintf(logtext + methodindent, "called: ");
916 utf_sprint(logtext + strlen(logtext), method->class->name);
917 sprintf(logtext + strlen(logtext), ".");
918 utf_sprint(logtext + strlen(logtext), method->name);
919 utf_sprint(logtext + strlen(logtext), method->descriptor);
925 void builtin_displaymethodstop(methodinfo *method, s8 l, double d, float f)
928 for (i = 0; i < methodindent; i++)
931 sprintf(logtext + methodindent, "finished: ");
932 utf_sprint(logtext + strlen(logtext), method->class->name);
933 sprintf(logtext + strlen(logtext), ".");
934 utf_sprint(logtext + strlen(logtext), method->name);
935 utf_sprint(logtext + strlen(logtext), method->descriptor);
937 switch (method->returntype) {
939 sprintf(logtext + strlen(logtext), "->%d", (s4) l);
942 #if defined(__I386__)
943 sprintf(logtext + strlen(logtext), "->%lld", (s8) l);
945 sprintf(logtext + strlen(logtext), "->%ld", (s8) l);
949 #if defined(__I386__)
950 sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l));
952 sprintf(logtext + strlen(logtext), "->%p", (u1*) l);
956 sprintf(logtext + strlen(logtext), "->%g", f);
959 sprintf(logtext + strlen(logtext), "->%g", d);
966 void builtin_displaymethodexception(methodinfo *method)
969 for (i = 0; i < methodindent; i++)
971 sprintf(logtext + methodindent, "exception abort: ");
972 utf_sprint(logtext + strlen(logtext), method->class->name);
973 sprintf(logtext + strlen(logtext), ".");
974 utf_sprint(logtext + strlen(logtext), method->name);
975 utf_sprint(logtext + strlen(logtext), method->descriptor);
980 /****************************************************************************
981 SYNCHRONIZATION FUNCTIONS
982 *****************************************************************************/
985 * Lock the mutex of an object.
989 internal_lock_mutex_for_object (java_objectheader *object)
991 mutexHashEntry *entry;
996 hashValue = MUTEX_HASH_VALUE(object);
997 entry = &mutexHashTable[hashValue];
999 if (entry->object != 0) {
1000 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1002 entry->mutex.holder = 0;
1003 entry->mutex.count = 0;
1004 entry->mutex.muxWaiters = 0;
1007 while (entry->next != 0 && entry->object != object)
1008 entry = entry->next;
1010 if (entry->object != object) {
1011 entry->next = firstFreeOverflowEntry;
1012 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1014 entry = entry->next;
1017 assert(entry->conditionCount == 0);
1022 entry->mutex.holder = 0;
1023 entry->mutex.count = 0;
1024 entry->mutex.muxWaiters = 0;
1027 if (entry->object == 0)
1028 entry->object = object;
1030 internal_lock_mutex(&entry->mutex);
1036 * Unlocks the mutex of an object.
1040 internal_unlock_mutex_for_object (java_objectheader *object)
1043 mutexHashEntry *entry;
1045 hashValue = MUTEX_HASH_VALUE(object);
1046 entry = &mutexHashTable[hashValue];
1048 if (entry->object == object) {
1049 internal_unlock_mutex(&entry->mutex);
1052 while (entry->next != 0 && entry->next->object != object)
1053 entry = entry->next;
1055 assert(entry->next != 0);
1057 internal_unlock_mutex(&entry->next->mutex);
1059 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1060 mutexHashEntry *unlinked = entry->next;
1062 entry->next = unlinked->next;
1063 unlinked->next = firstFreeOverflowEntry;
1064 firstFreeOverflowEntry = unlinked;
1071 void builtin_monitorenter(java_objectheader *o)
1076 assert(blockInts == 0);
1080 hashValue = MUTEX_HASH_VALUE(o);
1081 if (mutexHashTable[hashValue].object == o
1082 && mutexHashTable[hashValue].mutex.holder == currentThread)
1083 ++mutexHashTable[hashValue].mutex.count;
1085 internal_lock_mutex_for_object(o);
1089 assert(blockInts == 0);
1094 void builtin_monitorexit (java_objectheader *o)
1099 assert(blockInts == 0);
1103 hashValue = MUTEX_HASH_VALUE(o);
1104 if (mutexHashTable[hashValue].object == o) {
1105 if (mutexHashTable[hashValue].mutex.count == 1
1106 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1107 internal_unlock_mutex_for_object(o);
1109 --mutexHashTable[hashValue].mutex.count;
1112 internal_unlock_mutex_for_object(o);
1116 assert(blockInts == 0);
1121 /*****************************************************************************
1122 MISCELLANEOUS HELPER FUNCTIONS
1123 *****************************************************************************/
1127 /*********** Functions for integer divisions *****************************
1129 On some systems (eg. DEC ALPHA), integer division is not supported by the
1130 CPU. These helper functions implement the missing functionality.
1132 ******************************************************************************/
1134 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1135 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1138 /************** Functions for long arithmetics *******************************
1140 On systems where 64 bit Integers are not supported by the CPU, these
1141 functions are needed.
1143 ******************************************************************************/
1146 s8 builtin_ladd(s8 a, s8 b)
1151 return builtin_i2l(0);
1155 s8 builtin_lsub(s8 a, s8 b)
1160 return builtin_i2l(0);
1164 s8 builtin_lmul(s8 a, s8 b)
1169 return builtin_i2l(0);
1173 s8 builtin_ldiv(s8 a, s8 b)
1178 return builtin_i2l(0);
1182 s8 builtin_lrem(s8 a, s8 b)
1187 return builtin_i2l(0);
1191 s8 builtin_lshl(s8 a, s4 b)
1194 return a << (b & 63);
1196 return builtin_i2l(0);
1200 s8 builtin_lshr(s8 a, s4 b)
1203 return a >> (b & 63);
1205 return builtin_i2l(0);
1209 s8 builtin_lushr(s8 a, s4 b)
1212 return ((u8) a) >> (b & 63);
1214 return builtin_i2l(0);
1218 s8 builtin_land(s8 a, s8 b)
1223 return builtin_i2l(0);
1227 s8 builtin_lor(s8 a, s8 b)
1232 return builtin_i2l(0);
1236 s8 builtin_lxor(s8 a, s8 b)
1241 return builtin_i2l(0);
1245 s8 builtin_lneg(s8 a)
1250 return builtin_i2l(0);
1254 s4 builtin_lcmp(s8 a, s8 b)
1257 if (a < b) return -1;
1258 if (a > b) return 1;
1269 /*********** Functions for floating point operations *************************/
1271 float builtin_fadd(float a, float b)
1273 if (isnanf(a)) return FLT_NAN;
1274 if (isnanf(b)) return FLT_NAN;
1285 if (copysignf(1.0, a) == copysignf(1.0, b))
1294 float builtin_fsub(float a, float b)
1296 return builtin_fadd(a, builtin_fneg(b));
1300 float builtin_fmul(float a, float b)
1302 if (isnanf(a)) return FLT_NAN;
1303 if (isnanf(b)) return FLT_NAN;
1305 if (finitef(b)) return a*b;
1307 if (a == 0) return FLT_NAN;
1308 else return copysignf(b, copysignf(1.0, b)*a);
1313 if (b == 0) return FLT_NAN;
1314 else return copysignf(a, copysignf(1.0, a)*b);
1317 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1323 float builtin_fdiv(float a, float b)
1325 if (finitef(a) && finitef(b)) {
1339 float builtin_frem(float a, float b)
1345 float builtin_fneg(float a)
1347 if (isnanf(a)) return a;
1349 if (finitef(a)) return -a;
1350 else return copysignf(a, -copysignf(1.0, a));
1355 s4 builtin_fcmpl(float a, float b)
1357 if (isnanf(a)) return -1;
1358 if (isnanf(b)) return -1;
1359 if (!finitef(a) || !finitef(b)) {
1360 a = finitef(a) ? 0 : copysignf(1.0, a);
1361 b = finitef(b) ? 0 : copysignf(1.0, b);
1363 if (a > b) return 1;
1364 if (a == b) return 0;
1369 s4 builtin_fcmpg(float a, float b)
1371 if (isnanf(a)) return 1;
1372 if (isnanf(b)) return 1;
1373 if (!finitef(a) || !finitef(b)) {
1374 a = finitef(a) ? 0 : copysignf(1.0, a);
1375 b = finitef(b) ? 0 : copysignf(1.0, b);
1377 if (a > b) return 1;
1378 if (a == b) return 0;
1384 /************************* Functions for doubles ****************************/
1386 double builtin_dadd(double a, double b)
1388 if (isnan(a)) return DBL_NAN;
1389 if (isnan(b)) return DBL_NAN;
1391 if (finite(b)) return a+b;
1395 if (finite(b)) return a;
1397 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1398 else return DBL_NAN;
1404 double builtin_dsub(double a, double b)
1406 return builtin_dadd(a, builtin_dneg(b));
1410 double builtin_dmul(double a, double b)
1412 if (isnan(a)) return DBL_NAN;
1413 if (isnan(b)) return DBL_NAN;
1415 if (finite(b)) return a * b;
1417 if (a == 0) return DBL_NAN;
1418 else return copysign(b, copysign(1.0, b) * a);
1423 if (b == 0) return DBL_NAN;
1424 else return copysign(a, copysign(1.0, a) * b);
1427 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1433 double builtin_ddiv(double a, double b)
1435 if (finite(a) && finite(b)) {
1449 double builtin_drem(double a, double b)
1455 double builtin_dneg(double a)
1457 if (isnan(a)) return a;
1459 if (finite(a)) return -a;
1460 else return copysign(a, -copysign(1.0, a));
1465 s4 builtin_dcmpl(double a, double b)
1467 if (isnan(a)) return -1;
1468 if (isnan(b)) return -1;
1469 if (!finite(a) || !finite(b)) {
1470 a = finite(a) ? 0 : copysign(1.0, a);
1471 b = finite(b) ? 0 : copysign(1.0, b);
1473 if (a > b) return 1;
1474 if (a == b) return 0;
1479 s4 builtin_dcmpg(double a, double b)
1481 if (isnan(a)) return 1;
1482 if (isnan(b)) return 1;
1483 if (!finite(a) || !finite(b)) {
1484 a = finite(a) ? 0 : copysign(1.0, a);
1485 b = finite(b) ? 0 : copysign(1.0, b);
1487 if (a > b) return 1;
1488 if (a == b) return 0;
1493 /*********************** Conversion operations ****************************/
1495 s8 builtin_i2l(s4 i)
1500 s8 v; v.high = 0; v.low=i; return v;
1505 float builtin_i2f(s4 a)
1507 float f = (float) a;
1512 double builtin_i2d(s4 a)
1514 double d = (double) a;
1519 s4 builtin_l2i(s8 l)
1529 float builtin_l2f(s8 a)
1532 float f = (float) a;
1540 double builtin_l2d(s8 a)
1543 double d = (double) a;
1551 s4 builtin_f2i(float a)
1554 return builtin_d2i((double) a);
1563 if (a < (-2147483648))
1564 return (-2147483648);
1567 f = copysignf((float) 1.0, a);
1570 return (-2147483648); */
1574 s8 builtin_f2l(float a)
1577 return builtin_d2l((double) a);
1582 if (a > 9223372036854775807L)
1583 return 9223372036854775807L;
1584 if (a < (-9223372036854775808L))
1585 return (-9223372036854775808L);
1590 f = copysignf((float) 1.0, a);
1592 return 9223372036854775807L;
1593 return (-9223372036854775808L); */
1597 double builtin_f2d(float a)
1599 if (finitef(a)) return (double) a;
1604 return copysign(DBL_POSINF, (double) copysignf(1.0, a) );
1609 s4 builtin_d2i(double a)
1614 if (a >= 2147483647)
1616 if (a <= (-2147483647-1))
1617 return (-2147483647-1);
1622 d = copysign(1.0, a);
1625 return (-2147483647-1);
1629 s8 builtin_d2l(double a)
1634 if (a >= 9223372036854775807LL)
1635 return 9223372036854775807LL;
1636 if (a <= (-9223372036854775807LL-1))
1637 return (-9223372036854775807LL-1);
1642 d = copysign(1.0, a);
1644 return 9223372036854775807LL;
1645 return (-9223372036854775807LL-1);
1649 float builtin_d2f(double a)
1657 return copysignf(FLT_POSINF, (float) copysign(1.0, a));
1662 java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o) {
1663 return Java_java_lang_VMObject_clone ( 0 , 0, o);
1668 * These are local overrides for various environment variables in Emacs.
1669 * Please do not remove this and leave it at the end of the file, where
1670 * Emacs will automagically detect them.
1671 * ---------------------------------------------------------------------
1674 * indent-tabs-mode: t