1 /* src/vm/builtin.c - functions for unsupported operations
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
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 Changes: Christian Thalinger
33 Contains C functions for JavaVM Instructions that cannot be
34 translated to machine language directly. Consequently, the
35 generated machine code for these instructions contains function
36 calls instead of machine instructions, using the C calling
39 $Id: builtin.c 2825 2005-06-25 13:37:35Z twisti $
55 #include "mm/memory.h"
56 #include "native/native.h"
57 #include "native/include/java_lang_Cloneable.h"
58 #include "native/include/java_lang_Object.h" /* required by VMObject */
59 #include "native/include/java_lang_VMObject.h"
61 #if defined(USE_THREADS)
62 # if defined(NATIVE_THREADS)
63 # include "threads/native/threads.h"
65 # include "threads/green/threads.h"
66 # include "threads/green/locks.h"
70 #include "toolbox/logging.h"
71 #include "toolbox/util.h"
72 #include "vm/builtin.h"
73 #include "vm/exceptions.h"
74 #include "vm/global.h"
75 #include "vm/initialize.h"
76 #include "vm/loader.h"
77 #include "vm/options.h"
78 #include "vm/stringlocal.h"
79 #include "vm/tables.h"
80 #include "vm/jit/asmpart.h"
81 #include "vm/jit/patcher.h"
84 #undef DEBUG /*define DEBUG 1*/
86 THREADSPECIFIC methodinfo* _threadrootmethod = NULL;
87 THREADSPECIFIC void *_thread_nativestackframeinfo = NULL;
90 /* include builtin tables *****************************************************/
92 #include "vm/builtintable.inc"
95 /* builtintable_init ***********************************************************
97 Parse the descriptors of builtin functions and create the parsed
100 *******************************************************************************/
102 static bool builtintable_init(void)
104 descriptor_pool *descpool;
108 s4 entries_automatic;
111 /* mark start of dump memory area */
113 dumpsize = dump_size();
115 /* create a new descriptor pool */
117 descpool = descriptor_pool_new(class_java_lang_Object);
119 /* add some entries we need */
121 if (!descriptor_pool_add_class(descpool, utf_java_lang_Object))
124 if (!descriptor_pool_add_class(descpool, utf_java_lang_Class))
127 /* calculate table entries statically */
130 sizeof(builtintable_internal) / sizeof(builtintable_entry);
133 sizeof(builtintable_automatic) / sizeof(builtintable_entry)
134 - 1; /* last filler entry (comment see builtintable.inc) */
136 /* first add all descriptors to the pool */
138 for (i = 0; i < entries_internal; i++) {
139 /* create a utf8 string from descriptor */
141 descriptor = utf_new_char(builtintable_internal[i].descriptor);
143 if (!descriptor_pool_add(descpool, descriptor, NULL)) {
144 /* release dump area */
146 dump_release(dumpsize);
152 for (i = 0; i < entries_automatic; i++) {
153 /* create a utf8 string from descriptor */
155 descriptor = utf_new_char(builtintable_automatic[i].descriptor);
157 if (!descriptor_pool_add(descpool, descriptor, NULL)) {
158 /* release dump area */
160 dump_release(dumpsize);
166 /* create the class reference table */
168 (void) descriptor_pool_create_classrefs(descpool, NULL);
170 /* allocate space for the parsed descriptors */
172 descriptor_pool_alloc_parsed_descriptors(descpool);
174 /* now parse all descriptors */
176 for (i = 0; i < entries_internal; i++) {
177 /* create a utf8 string from descriptor */
179 descriptor = utf_new_char(builtintable_internal[i].descriptor);
181 /* parse the descriptor, builtin is always static (no `this' pointer) */
183 builtintable_internal[i].md =
184 descriptor_pool_parse_method_descriptor(descpool, descriptor,
188 for (i = 0; i < entries_automatic; i++) {
189 /* create a utf8 string from descriptor */
191 descriptor = utf_new_char(builtintable_automatic[i].descriptor);
193 /* parse the descriptor, builtin is always static (no `this' pointer) */
195 builtintable_automatic[i].md =
196 descriptor_pool_parse_method_descriptor(descpool, descriptor,
200 /* release dump area */
202 dump_release(dumpsize);
208 /* builtintable_comparator *****************************************************
210 qsort comparator for the automatic builtin table.
212 *******************************************************************************/
214 static int builtintable_comparator(const void *a, const void *b)
216 builtintable_entry *bte1;
217 builtintable_entry *bte2;
219 bte1 = (builtintable_entry *) a;
220 bte2 = (builtintable_entry *) b;
222 return (bte1->opcode < bte2->opcode) ? -1 : (bte1->opcode > bte2->opcode);
226 /* builtintable_sort_automatic *************************************************
228 Sorts the automatic builtin table.
230 *******************************************************************************/
232 static void builtintable_sort_automatic(void)
236 /* calculate table size statically (`- 1' comment see builtintable.inc) */
238 entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
240 qsort(builtintable_automatic, entries, sizeof(builtintable_entry),
241 builtintable_comparator);
245 /* builtin_init ****************************************************************
249 *******************************************************************************/
251 bool builtin_init(void)
253 /* initialize the builtin tables */
255 if (!builtintable_init())
258 /* sort builtin tables */
260 builtintable_sort_automatic();
266 /* builtintable_entry_debug_dump ***********************************************
268 Prints a builtintable_entry in human-readable form.
270 *******************************************************************************/
272 void builtintable_entry_debug_dump(FILE *file, builtintable_entry *bte)
278 fprintf(file,"(builtintable_entry *)NULL");
284 name = "<name=NULL>";
285 desc = (bte->md) ? "parsed " : bte->descriptor;
287 desc = "<desc=NULL>";
288 fprintf(file,"BUILTIN(%d,%p,%s %s",
289 bte->opcode,(void*)bte->fp,name,desc);
290 descriptor_debug_print_methoddesc(file,bte->md);
295 /* builtintable_get_internal ***************************************************
297 Finds an entry in the builtintable for internal functions and
298 returns the a pointer to the structure.
300 *******************************************************************************/
302 builtintable_entry *builtintable_get_internal(functionptr fp)
306 for (i = 0; builtintable_internal[i].fp != NULL; i++) {
307 if (builtintable_internal[i].fp == fp)
308 return &builtintable_internal[i];
315 /* builtintable_get_automatic **************************************************
317 Finds an entry in the builtintable for functions which are replaced
318 automatically and returns the a pointer to the structure.
320 *******************************************************************************/
322 builtintable_entry *builtintable_get_automatic(s4 opcode)
324 builtintable_entry *first;
325 builtintable_entry *last;
326 builtintable_entry *middle;
330 /* calculate table size statically (`- 1' comment see builtintable.inc) */
332 entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
334 first = builtintable_automatic;
335 last = builtintable_automatic + entries;
337 while (entries > 0) {
339 middle = first + half;
341 if (middle->opcode < opcode) {
348 return (first != last ? first : NULL);
352 /*****************************************************************************
354 *****************************************************************************/
358 /*************** internal function: builtin_isanysubclass *********************
360 Checks a subclass relation between two classes. Implemented interfaces
361 are interpreted as super classes.
362 Return value: 1 ... sub is subclass of super
365 *****************************************************************************/
366 s4 builtin_isanysubclass(classinfo *sub, classinfo *super)
369 castinfo classvalues;
374 if (super->flags & ACC_INTERFACE)
375 return (sub->vftbl->interfacetablelength > super->index) &&
376 (sub->vftbl->interfacetable[-super->index] != NULL);
378 asm_getclassvalues_atomic(super->vftbl, sub->vftbl, &classvalues);
380 res = (u4) (classvalues.sub_baseval - classvalues.super_baseval) <=
381 (u4) classvalues.super_diffval;
387 s4 builtin_isanysubclass_vftbl(vftbl_t *sub, vftbl_t *super)
391 castinfo classvalues;
396 asm_getclassvalues_atomic(super, sub, &classvalues);
398 if ((base = classvalues.super_baseval) <= 0)
399 /* super is an interface */
400 res = (sub->interfacetablelength > -base) &&
401 (sub->interfacetable[base] != NULL);
403 res = (u4) (classvalues.sub_baseval - classvalues.super_baseval)
404 <= (u4) classvalues.super_diffval;
410 /****************** function: builtin_instanceof *****************************
412 Checks if an object is an instance of some given class (or subclass of
413 that class). If class is an interface, checks if the interface is
415 Return value: 1 ... obj is an instance of class or implements the interface
416 0 ... otherwise or if obj == NULL
418 *****************************************************************************/
420 /* XXX should use vftbl */
421 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
424 log_text ("builtin_instanceof called");
429 return builtin_isanysubclass(obj->vftbl->class, class);
434 /**************** function: builtin_checkcast *******************************
436 The same as builtin_instanceof except that 1 is returned when
439 ****************************************************************************/
441 /* XXX should use vftbl */
442 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
445 log_text("builtin_checkcast called");
450 if (builtin_isanysubclass(obj->vftbl->class, class))
454 printf("#### checkcast failed ");
455 utf_display(obj->vftbl->class->name);
457 utf_display(class->name);
465 /* builtin_descriptorscompatible ***********************************************
467 Checks if two array type descriptors are assignment compatible
469 Return value: 1 ... target = desc is possible
472 *******************************************************************************/
474 static s4 builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
479 if (desc->arraytype != target->arraytype)
482 if (desc->arraytype != ARRAYTYPE_OBJECT)
485 /* {both arrays are arrays of references} */
487 if (desc->dimension == target->dimension) {
488 /* an array which contains elements of interface types is allowed to be casted to Object (JOWENN)*/
489 if ( (desc->elementvftbl->baseval<0) && (target->elementvftbl->baseval==1) ) return 1;
490 return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
492 if (desc->dimension < target->dimension) return 0;
494 /* {desc has higher dimension than target} */
495 return builtin_isanysubclass_vftbl(pseudo_class_Arraystub->vftbl, target->elementvftbl);
499 /* builtin_arraycheckcast ******************************************************
501 Checks if an object is really a subtype of the requested array
502 type. The object has to be an array to begin with. For simple
503 arrays (int, short, double, etc.) the types have to match exactly.
504 For arrays of objects, the type of elements in the array has to be
505 a subtype (or the same type) of the requested element type. For
506 arrays of arrays (which in turn can again be arrays of arrays), the
507 types at the lowest level have to satisfy the corresponding sub
510 *******************************************************************************/
512 s4 builtin_arraycheckcast(java_objectheader *o, vftbl_t *target)
514 arraydescriptor *desc;
519 if ((desc = o->vftbl->arraydesc) == NULL)
522 return builtin_descriptorscompatible(desc, target->arraydesc);
526 s4 builtin_arrayinstanceof(java_objectheader *obj, vftbl_t *target)
531 return builtin_arraycheckcast(obj, target);
535 /************************** exception functions *******************************
537 ******************************************************************************/
539 java_objectheader *builtin_throw_exception(java_objectheader *xptr)
541 java_lang_Throwable *t;
547 t = (java_lang_Throwable *) xptr;
549 /* calculate message length */
551 logtextlen = strlen("Builtin exception thrown: ") + strlen("0");
555 utf_strlen(xptr->vftbl->class->name) +
557 javastring_strlen((java_objectheader *) t->detailMessage);
560 logtextlen += strlen("(nil)");
562 /* allocate memory */
564 dumpsize = dump_size();
566 logtext = DMNEW(char, logtextlen);
568 strcpy(logtext, "Builtin exception thrown: ");
571 utf_sprint_classname(logtext + strlen(logtext),
572 xptr->vftbl->class->name);
574 if (t->detailMessage) {
577 buf = javastring_tochar((java_objectheader *) t->detailMessage);
578 strcat(logtext, ": ");
579 strcat(logtext, buf);
580 MFREE(buf, char, strlen(buf));
584 strcat(logtext, "(nil)");
591 dump_release(dumpsize);
594 *exceptionptr = xptr;
601 /* builtin_canstore ************************************************************
603 Checks, if an object can be stored in an array.
605 Return value: 1 ... possible
608 *******************************************************************************/
610 s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
612 arraydescriptor *desc;
613 arraydescriptor *valuedesc;
614 vftbl_t *componentvftbl;
617 castinfo classvalues;
622 /* The following is guaranteed (by verifier checks):
624 * *) a->...vftbl->arraydesc != NULL
625 * *) a->...vftbl->arraydesc->componentvftbl != NULL
626 * *) o->vftbl is not an interface vftbl
629 desc = a->header.objheader.vftbl->arraydesc;
630 componentvftbl = desc->componentvftbl;
631 valuevftbl = o->vftbl;
633 if ((desc->dimension - 1) == 0) {
636 /* {a is a one-dimensional array} */
637 /* {a is an array of references} */
639 if (valuevftbl == componentvftbl)
642 asm_getclassvalues_atomic(componentvftbl, valuevftbl, &classvalues);
644 if ((base = classvalues.super_baseval) <= 0)
645 /* an array of interface references */
646 return (valuevftbl->interfacetablelength > -base &&
647 valuevftbl->interfacetable[base] != NULL);
649 res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
650 <= (unsigned) classvalues.super_diffval;
655 /* {a has dimension > 1} */
656 /* {componentvftbl->arraydesc != NULL} */
658 /* check if o is an array */
659 if ((valuedesc = valuevftbl->arraydesc) == NULL)
661 /* {o is an array} */
663 return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
667 /* This is an optimized version where a is guaranteed to be one-dimensional */
668 s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
670 arraydescriptor *desc;
671 vftbl_t *elementvftbl;
675 castinfo classvalues;
679 /* The following is guaranteed (by verifier checks):
681 * *) a->...vftbl->arraydesc != NULL
682 * *) a->...vftbl->arraydesc->elementvftbl != NULL
683 * *) a->...vftbl->arraydesc->dimension == 1
684 * *) o->vftbl is not an interface vftbl
687 desc = a->header.objheader.vftbl->arraydesc;
688 elementvftbl = desc->elementvftbl;
689 valuevftbl = o->vftbl;
691 /* {a is a one-dimensional array} */
693 if (valuevftbl == elementvftbl)
696 asm_getclassvalues_atomic(elementvftbl, valuevftbl, &classvalues);
698 if ((base = classvalues.super_baseval) <= 0)
699 /* an array of interface references */
700 return (valuevftbl->interfacetablelength > -base &&
701 valuevftbl->interfacetable[base] != NULL);
703 res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
704 <= (unsigned) classvalues.super_diffval;
710 /* This is an optimized version where a is guaranteed to be a
711 * one-dimensional array of a class type */
712 s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
714 vftbl_t *elementvftbl;
717 castinfo classvalues;
721 /* The following is guaranteed (by verifier checks):
723 * *) a->...vftbl->arraydesc != NULL
724 * *) a->...vftbl->arraydesc->elementvftbl != NULL
725 * *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
726 * *) a->...vftbl->arraydesc->dimension == 1
727 * *) o->vftbl is not an interface vftbl
730 elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
731 valuevftbl = o->vftbl;
733 /* {a is a one-dimensional array} */
735 if (valuevftbl == elementvftbl)
738 asm_getclassvalues_atomic(elementvftbl, valuevftbl, &classvalues);
740 res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
741 <= (unsigned) classvalues.super_diffval;
747 /* builtin_new *****************************************************************
749 Creates a new instance of class c on the heap.
751 Return value: pointer to the object or NULL if no memory is
754 *******************************************************************************/
756 java_objectheader *builtin_new(classinfo *c)
758 java_objectheader *o;
760 /* is the class loaded */
761 /*utf_fprint(stderr,c->name);fprintf(stderr,"\n");*/
764 /* is the class linked */
769 if (!c->initialized) {
771 log_message_class("Initialize class (from builtin_new): ", c);
773 if (!initialize_class(c))
777 o = heap_allocate(c->instancesize, true, c->finalizer);
782 MSET(o, 0, u1, c->instancesize);
786 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
794 /* builtin_newarray ************************************************************
796 Creates an array with the given vftbl on the heap.
798 Return value: pointer to the array or NULL if no memory is available
800 CAUTION: The given vftbl must be the vftbl of the *array* class,
801 not of the element class.
803 *******************************************************************************/
805 java_arrayheader *builtin_newarray(s4 size, vftbl_t *arrayvftbl)
808 arraydescriptor *desc;
813 desc = arrayvftbl->arraydesc;
814 dataoffset = desc->dataoffset;
815 componentsize = desc->componentsize;
818 *exceptionptr = new_negativearraysizeexception();
822 actualsize = dataoffset + size * componentsize;
824 if (((u4) actualsize) < ((u4) size)) { /* overflow */
825 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
829 a = heap_allocate(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL);
834 MSET(a, 0, u1, actualsize);
836 a->objheader.vftbl = arrayvftbl;
838 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
839 initObjectLock(&a->objheader);
848 /* builtin_anewarray ***********************************************************
850 Creates an array of references to the given class type on the heap.
852 Return value: pointer to the array or NULL if no memory is
855 *******************************************************************************/
857 java_objectarray *builtin_anewarray(s4 size, classinfo *component)
861 /* is class loaded */
862 assert(component->loaded);
864 /* is class linked */
865 if (!component->linked)
866 if (!link_class(component))
869 c = class_array_of(component, true);
874 return (java_objectarray *) builtin_newarray(size, c->vftbl);
878 /* builtin_newarray_int ********************************************************
880 Creates an array of 32 bit Integers on the heap.
882 Return value: pointer to the array or NULL if no memory is
885 *******************************************************************************/
887 java_intarray *builtin_newarray_int(s4 size)
889 return (java_intarray *)
890 builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
894 /* builtin_newarray_long *******************************************************
896 Creates an array of 64 bit Integers on the heap.
898 Return value: pointer to the array or NULL if no memory is
901 *******************************************************************************/
903 java_longarray *builtin_newarray_long(s4 size)
905 return (java_longarray *)
906 builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
910 /* builtin_newarray_float ******************************************************
912 Creates an array of 32 bit IEEE floats on the heap.
914 Return value: pointer to the array or NULL if no memory is
917 *******************************************************************************/
919 java_floatarray *builtin_newarray_float(s4 size)
921 return (java_floatarray *)
922 builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
926 /* builtin_newarray_double *****************************************************
928 Creates an array of 64 bit IEEE floats on the heap.
930 Return value: pointer to the array or NULL if no memory is
933 *******************************************************************************/
935 java_doublearray *builtin_newarray_double(s4 size)
937 return (java_doublearray *)
938 builtin_newarray(size,
939 primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
943 /* builtin_newarray_byte *******************************************************
945 Creates an array of 8 bit Integers on the heap.
947 Return value: pointer to the array or NULL if no memory is
950 *******************************************************************************/
952 java_bytearray *builtin_newarray_byte(s4 size)
954 return (java_bytearray *)
955 builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
959 /* builtin_newarray_char *******************************************************
961 Creates an array of characters on the heap.
963 Return value: pointer to the array or NULL if no memory is
966 *******************************************************************************/
968 java_chararray *builtin_newarray_char(s4 size)
970 return (java_chararray *)
971 builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
975 /* builtin_newarray_short ******************************************************
977 Creates an array of 16 bit Integers on the heap.
979 Return value: pointer to the array or NULL if no memory is
982 *******************************************************************************/
984 java_shortarray *builtin_newarray_short(s4 size)
986 return (java_shortarray *)
987 builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
991 /* builtin_newarray_boolean ****************************************************
993 Creates an array of bytes on the heap. The array is designated as
994 an array of booleans (important for casts)
996 Return value: pointer to the array or NULL if no memory is
999 *******************************************************************************/
1001 java_booleanarray *builtin_newarray_boolean(s4 size)
1003 return (java_booleanarray *)
1004 builtin_newarray(size,
1005 primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
1009 /* builtin_multianewarray ******************************************************
1011 Creates a multi-dimensional array on the heap. The dimensions are
1012 passed in an array of longs.
1015 n............number of dimensions to create
1016 arrayvftbl...vftbl of the array class
1017 dims.........array containing the size of each dimension to create
1019 Return value: pointer to the array or NULL if no memory is
1022 ******************************************************************************/
1024 java_arrayheader *builtin_multianewarray(int n, vftbl_t *arrayvftbl, long *dims)
1027 java_arrayheader *a;
1028 vftbl_t *componentvftbl;
1030 /* create this dimension */
1032 size = (s4) dims[0];
1033 a = builtin_newarray(size, arrayvftbl);
1038 /* if this is the last dimension return */
1043 /* get the vftbl of the components to create */
1045 componentvftbl = arrayvftbl->arraydesc->componentvftbl;
1047 /* The verifier guarantees that the dimension count is in the range. */
1049 /* create the component arrays */
1051 for (i = 0; i < size; i++) {
1052 java_arrayheader *ea =
1053 builtin_multianewarray(n, componentvftbl, dims + 1);
1058 ((java_objectarray *) a)->data[i] = (java_objectheader *) ea;
1065 /*****************************************************************************
1068 Various functions for printing a message at method entry or exit (for
1071 *****************************************************************************/
1073 u4 methodindent = 0;
1075 java_objectheader *builtin_trace_exception(java_objectheader *xptr,
1089 log_text("WARNING: unmatched methodindent--");
1092 if (opt_verbose || runverbose || verboseexception) {
1093 /* calculate message length */
1097 strlen("Exception ") +
1098 utf_strlen(xptr->vftbl->class->name);
1101 logtextlen = strlen("Some Throwable");
1103 logtextlen += strlen(" thrown in ");
1107 utf_strlen(m->class->name) +
1109 utf_strlen(m->name) +
1110 strlen("(NOSYNC,NATIVE");
1112 #if SIZEOF_VOID_P == 8
1114 strlen(")(0x123456789abcdef0) at position 0x123456789abcdef0 (");
1116 logtextlen += strlen(")(0x12345678) at position 0x12345678 (");
1119 if (m->class->sourcefile == NULL)
1120 logtextlen += strlen("<NO CLASSFILE INFORMATION>");
1122 logtextlen += utf_strlen(m->class->sourcefile);
1124 logtextlen += strlen(":65536)");
1127 logtextlen += strlen("call_java_method");
1129 logtextlen += strlen("0");
1131 /* allocate memory */
1133 dumpsize = dump_size();
1135 logtext = DMNEW(char, logtextlen);
1138 strcpy(logtext, "Exception ");
1139 utf_strcat_classname(logtext, xptr->vftbl->class->name);
1142 strcpy(logtext, "Some Throwable");
1145 strcat(logtext, " thrown in ");
1148 utf_strcat_classname(logtext, m->class->name);
1149 strcat(logtext, ".");
1150 utf_strcat(logtext, m->name);
1152 if (m->flags & ACC_SYNCHRONIZED)
1153 strcat(logtext, "(SYNC");
1155 strcat(logtext, "(NOSYNC");
1157 if (m->flags & ACC_NATIVE) {
1158 strcat(logtext, ",NATIVE");
1160 #if SIZEOF_VOID_P == 8
1161 sprintf(logtext + strlen(logtext),
1162 ")(0x%016lx) at position 0x%016lx",
1163 (ptrint) m->entrypoint, (ptrint) pos);
1165 sprintf(logtext + strlen(logtext),
1166 ")(0x%08x) at position 0x%08x",
1167 (ptrint) m->entrypoint, (ptrint) pos);
1171 #if SIZEOF_VOID_P == 8
1172 sprintf(logtext + strlen(logtext),
1173 ")(0x%016lx) at position 0x%016lx (",
1174 (ptrint) m->entrypoint, (ptrint) pos);
1176 sprintf(logtext + strlen(logtext),
1177 ")(0x%08x) at position 0x%08x (",
1178 (ptrint) m->entrypoint, (ptrint) pos);
1181 if (m->class->sourcefile == NULL)
1182 strcat(logtext, "<NO CLASSFILE INFORMATION>");
1184 utf_strcat(logtext, m->class->sourcefile);
1186 sprintf(logtext + strlen(logtext), ":%d)", line);
1190 strcat(logtext, "call_java_method");
1194 /* release memory */
1196 dump_release(dumpsize);
1203 /* builtin_trace_args **********************************************************
1207 *******************************************************************************/
1209 #ifdef TRACE_ARGS_NUM
1210 void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3,
1211 #if TRACE_ARGS_NUM >= 6
1214 #if TRACE_ARGS_NUM == 8
1227 /* calculate message length */
1230 methodindent + strlen("called: ") +
1231 utf_strlen(m->class->name) +
1233 utf_strlen(m->name) +
1234 utf_strlen(m->descriptor) +
1235 strlen(" SYNCHRONIZED") + strlen("(") + strlen(")");
1237 /* add maximal argument length */
1239 logtextlen += strlen("0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, ...(255)");
1241 /* allocate memory */
1243 dumpsize = dump_size();
1245 logtext = DMNEW(char, logtextlen);
1247 for (i = 0; i < methodindent; i++)
1250 strcpy(logtext + methodindent, "called: ");
1252 utf_strcat_classname(logtext, m->class->name);
1253 strcat(logtext, ".");
1254 utf_strcat(logtext, m->name);
1255 utf_strcat(logtext, m->descriptor);
1257 if (m->flags & ACC_PUBLIC) strcat(logtext, " PUBLIC");
1258 if (m->flags & ACC_PRIVATE) strcat(logtext, " PRIVATE");
1259 if (m->flags & ACC_PROTECTED) strcat(logtext, " PROTECTED");
1260 if (m->flags & ACC_STATIC) strcat(logtext, " STATIC");
1261 if (m->flags & ACC_FINAL) strcat(logtext, " FINAL");
1262 if (m->flags & ACC_SYNCHRONIZED) strcat(logtext, " SYNCHRONIZED");
1263 if (m->flags & ACC_VOLATILE) strcat(logtext, " VOLATILE");
1264 if (m->flags & ACC_TRANSIENT) strcat(logtext, " TRANSIENT");
1265 if (m->flags & ACC_NATIVE) strcat(logtext, " NATIVE");
1266 if (m->flags & ACC_INTERFACE) strcat(logtext, " INTERFACE");
1267 if (m->flags & ACC_ABSTRACT) strcat(logtext, " ABSTRACT");
1269 strcat(logtext, "(");
1271 switch (md->paramcount) {
1275 #if SIZEOF_VOID_P == 4
1277 sprintf(logtext + strlen(logtext),
1283 sprintf(logtext + strlen(logtext),
1289 sprintf(logtext + strlen(logtext),
1290 "0x%llx, 0x%llx, 0x%llx",
1295 sprintf(logtext + strlen(logtext),
1296 "0x%llx, 0x%llx, 0x%llx, 0x%llx",
1300 #if TRACE_ARGS_NUM >= 6
1302 sprintf(logtext + strlen(logtext),
1303 "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx",
1304 a0, a1, a2, a3, a4);
1308 sprintf(logtext + strlen(logtext),
1309 "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx",
1310 a0, a1, a2, a3, a4, a5);
1312 #endif /* TRACE_ARGS_NUM >= 6 */
1314 #if TRACE_ARGS_NUM == 8
1316 sprintf(logtext + strlen(logtext),
1317 "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx",
1318 a0, a1, a2, a3, a4, a5, a6);
1322 sprintf(logtext + strlen(logtext),
1323 "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx",
1324 a0, a1, a2, a3, a4, a5, a6, a7);
1326 #endif /* TRACE_ARGS_NUM == 8 */
1329 #if TRACE_ARGS_NUM == 4
1330 sprintf(logtext + strlen(logtext),
1331 "0x%llx, 0x%llx, 0x%llx, 0x%llx, ...(%d)",
1332 a0, a1, a2, a3, m->paramcount - 4);
1334 #elif TRACE_ARGS_NUM == 6
1335 sprintf(logtext + strlen(logtext),
1336 "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, ...(%d)",
1337 a0, a1, a2, a3, a4, a5, m->paramcount - 6);
1339 #elif TRACE_ARGS_NUM == 8
1340 sprintf(logtext + strlen(logtext),
1341 "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, ...(%d)",
1342 a0, a1, a2, a3, a4, a5, a6, a7, m->paramcount - 8);
1346 #else /* SIZEOF_VOID_P == 4 */
1349 sprintf(logtext + strlen(logtext),
1355 sprintf(logtext + strlen(logtext),
1361 sprintf(logtext + strlen(logtext),
1362 "0x%lx, 0x%lx, 0x%lx", a0, a1, a2);
1366 sprintf(logtext + strlen(logtext),
1367 "0x%lx, 0x%lx, 0x%lx, 0x%lx",
1371 #if TRACE_ARGS_NUM >= 6
1373 sprintf(logtext + strlen(logtext),
1374 "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
1375 a0, a1, a2, a3, a4);
1379 sprintf(logtext + strlen(logtext),
1380 "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
1381 a0, a1, a2, a3, a4, a5);
1383 #endif /* TRACE_ARGS_NUM >= 6 */
1385 #if TRACE_ARGS_NUM == 8
1387 sprintf(logtext + strlen(logtext),
1388 "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
1389 a0, a1, a2, a3, a4, a5, a6);
1393 sprintf(logtext + strlen(logtext),
1394 "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
1395 a0, a1, a2, a3, a4, a5, a6, a7);
1397 #endif /* TRACE_ARGS_NUM == 8 */
1400 #if TRACE_ARGS_NUM == 4
1401 sprintf(logtext + strlen(logtext),
1402 "0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)",
1403 a0, a1, a2, a3, m->paramcount - 4);
1405 #elif TRACE_ARGS_NUM == 6
1406 sprintf(logtext + strlen(logtext),
1407 "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)",
1408 a0, a1, a2, a3, a4, a5, m->paramcount - 6);
1410 #elif TRACE_ARGS_NUM == 8
1411 sprintf(logtext + strlen(logtext),
1412 "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)",
1413 a0, a1, a2, a3, a4, a5, a6, a7, m->paramcount - 8);
1416 #endif /* SIZEOF_VOID_P == 4 */
1419 strcat(logtext, ")");
1423 /* release memory */
1425 dump_release(dumpsize);
1432 /* builtin_displaymethodstop ***************************************************
1436 *******************************************************************************/
1438 void builtin_displaymethodstop(methodinfo *m, s8 l, double d, float f)
1449 /* calculate message length */
1452 methodindent + strlen("finished: ") +
1453 utf_strlen(m->class->name) +
1455 utf_strlen(m->name) +
1456 utf_strlen(m->descriptor) +
1457 strlen(" SYNCHRONIZED") + strlen("(") + strlen(")");
1459 /* add maximal argument length */
1461 logtextlen += strlen("->0.4872328470301428 (0x0123456789abcdef)");
1463 /* allocate memory */
1465 dumpsize = dump_size();
1467 logtext = DMNEW(char, logtextlen);
1469 /* generate the message */
1471 for (i = 0; i < methodindent; i++)
1477 log_text("WARNING: unmatched methodindent--");
1479 strcpy(logtext + methodindent, "finished: ");
1480 utf_strcat_classname(logtext, m->class->name);
1481 strcat(logtext, ".");
1482 utf_strcat(logtext, m->name);
1483 utf_strcat(logtext, m->descriptor);
1485 switch (md->returntype.type) {
1487 sprintf(logtext + strlen(logtext), "->%d (0x%08x)", (s4) l, (s4) l);
1491 #if SIZEOF_VOID_P == 4
1492 sprintf(logtext + strlen(logtext), "->%lld (0x%016llx)", (s8) l, l);
1494 sprintf(logtext + strlen(logtext), "->%ld (0x%016lx)", (s8) l, l);
1499 sprintf(logtext + strlen(logtext), "->%p", (void *) (ptrint) l);
1504 sprintf(logtext + strlen(logtext), "->%.8f (0x%08x)", f, imu.i);
1509 #if SIZEOF_VOID_P == 4
1510 sprintf(logtext + strlen(logtext), "->%.16g (0x%016llx)", d, imu.l);
1512 sprintf(logtext + strlen(logtext), "->%.16g (0x%016lx)", d, imu.l);
1519 /* release memory */
1521 dump_release(dumpsize);
1525 /****************************************************************************
1526 SYNCHRONIZATION FUNCTIONS
1527 *****************************************************************************/
1529 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1531 * Lock the mutex of an object.
1533 void internal_lock_mutex_for_object(java_objectheader *object)
1535 mutexHashEntry *entry;
1538 assert(object != 0);
1540 hashValue = MUTEX_HASH_VALUE(object);
1541 entry = &mutexHashTable[hashValue];
1543 if (entry->object != 0) {
1544 if (entry->mutex.count == 0 && entry->conditionCount == 0) {
1546 entry->mutex.holder = 0;
1547 entry->mutex.count = 0;
1548 entry->mutex.muxWaiters = 0;
1551 while (entry->next != 0 && entry->object != object)
1552 entry = entry->next;
1554 if (entry->object != object) {
1555 entry->next = firstFreeOverflowEntry;
1556 firstFreeOverflowEntry = firstFreeOverflowEntry->next;
1558 entry = entry->next;
1561 assert(entry->conditionCount == 0);
1566 entry->mutex.holder = 0;
1567 entry->mutex.count = 0;
1568 entry->mutex.muxWaiters = 0;
1571 if (entry->object == 0)
1572 entry->object = object;
1574 internal_lock_mutex(&entry->mutex);
1579 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1581 * Unlocks the mutex of an object.
1583 void internal_unlock_mutex_for_object (java_objectheader *object)
1586 mutexHashEntry *entry;
1588 hashValue = MUTEX_HASH_VALUE(object);
1589 entry = &mutexHashTable[hashValue];
1591 if (entry->object == object) {
1592 internal_unlock_mutex(&entry->mutex);
1595 while (entry->next != 0 && entry->next->object != object)
1596 entry = entry->next;
1598 assert(entry->next != 0);
1600 internal_unlock_mutex(&entry->next->mutex);
1602 if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
1603 mutexHashEntry *unlinked = entry->next;
1605 entry->next = unlinked->next;
1606 unlinked->next = firstFreeOverflowEntry;
1607 firstFreeOverflowEntry = unlinked;
1614 #if defined(USE_THREADS)
1615 void builtin_monitorenter(java_objectheader *o)
1617 #if !defined(NATIVE_THREADS)
1622 hashValue = MUTEX_HASH_VALUE(o);
1623 if (mutexHashTable[hashValue].object == o
1624 && mutexHashTable[hashValue].mutex.holder == currentThread)
1625 ++mutexHashTable[hashValue].mutex.count;
1627 internal_lock_mutex_for_object(o);
1631 monitorEnter((threadobject *) THREADOBJECT, o);
1637 #if defined(USE_THREADS)
1639 * Locks the class object - needed for static synchronized methods.
1640 * The use_class_as_object call is needed in order to circumvent a
1641 * possible deadlock with builtin_monitorenter called by another
1642 * thread calling use_class_as_object.
1644 void builtin_staticmonitorenter(classinfo *c)
1646 use_class_as_object(c);
1647 builtin_monitorenter(&c->header);
1652 #if defined(USE_THREADS)
1653 void builtin_monitorexit(java_objectheader *o)
1655 #if !defined(NATIVE_THREADS)
1660 hashValue = MUTEX_HASH_VALUE(o);
1661 if (mutexHashTable[hashValue].object == o) {
1662 if (mutexHashTable[hashValue].mutex.count == 1
1663 && mutexHashTable[hashValue].mutex.muxWaiters != 0)
1664 internal_unlock_mutex_for_object(o);
1666 --mutexHashTable[hashValue].mutex.count;
1669 internal_unlock_mutex_for_object(o);
1673 monitorExit((threadobject *) THREADOBJECT, o);
1679 /*****************************************************************************
1680 MISCELLANEOUS HELPER FUNCTIONS
1681 *****************************************************************************/
1685 /*********** Functions for integer divisions *****************************
1687 On some systems (eg. DEC ALPHA), integer division is not supported by the
1688 CPU. These helper functions implement the missing functionality.
1690 ******************************************************************************/
1692 s4 builtin_idiv(s4 a, s4 b) { return a / b; }
1693 s4 builtin_irem(s4 a, s4 b) { return a % b; }
1696 /************** Functions for long arithmetics *******************************
1698 On systems where 64 bit Integers are not supported by the CPU, these
1699 functions are needed.
1701 ******************************************************************************/
1704 s8 builtin_ladd(s8 a, s8 b)
1709 return builtin_i2l(0);
1713 s8 builtin_lsub(s8 a, s8 b)
1718 return builtin_i2l(0);
1722 s8 builtin_lmul(s8 a, s8 b)
1727 return builtin_i2l(0);
1731 s8 builtin_ldiv(s8 a, s8 b)
1736 return builtin_i2l(0);
1740 s8 builtin_lrem(s8 a, s8 b)
1745 return builtin_i2l(0);
1749 s8 builtin_lshl(s8 a, s4 b)
1752 return a << (b & 63);
1754 return builtin_i2l(0);
1758 s8 builtin_lshr(s8 a, s4 b)
1761 return a >> (b & 63);
1763 return builtin_i2l(0);
1767 s8 builtin_lushr(s8 a, s4 b)
1770 return ((u8) a) >> (b & 63);
1772 return builtin_i2l(0);
1776 s8 builtin_land(s8 a, s8 b)
1781 return builtin_i2l(0);
1785 s8 builtin_lor(s8 a, s8 b)
1790 return builtin_i2l(0);
1794 s8 builtin_lxor(s8 a, s8 b)
1799 return builtin_i2l(0);
1803 s8 builtin_lneg(s8 a)
1808 return builtin_i2l(0);
1812 s4 builtin_lcmp(s8 a, s8 b)
1815 if (a < b) return -1;
1816 if (a > b) return 1;
1827 /*********** Functions for floating point operations *************************/
1829 float builtin_fadd(float a, float b)
1831 if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1832 if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1843 if (copysignf(1.0, a) == copysignf(1.0, b))
1846 return intBitsToFloat(FLT_NAN);
1852 float builtin_fsub(float a, float b)
1854 return builtin_fadd(a, builtin_fneg(b));
1858 float builtin_fmul(float a, float b)
1860 if (isnanf(a)) return intBitsToFloat(FLT_NAN);
1861 if (isnanf(b)) return intBitsToFloat(FLT_NAN);
1863 if (finitef(b)) return a * b;
1865 if (a == 0) return intBitsToFloat(FLT_NAN);
1866 else return copysignf(b, copysignf(1.0, b)*a);
1871 if (b == 0) return intBitsToFloat(FLT_NAN);
1872 else return copysignf(a, copysignf(1.0, a)*b);
1875 return copysignf(a, copysignf(1.0, a)*copysignf(1.0, b));
1881 float builtin_fdiv(float a, float b)
1883 if (finitef(a) && finitef(b)) {
1888 return intBitsToFloat(FLT_POSINF);
1890 return intBitsToFloat(FLT_NEGINF);
1893 return intBitsToFloat(FLT_NAN);
1897 float builtin_frem(float a, float b)
1903 float builtin_fneg(float a)
1905 if (isnanf(a)) return a;
1907 if (finitef(a)) return -a;
1908 else return copysignf(a, -copysignf(1.0, a));
1913 s4 builtin_fcmpl(float a, float b)
1915 if (isnanf(a)) return -1;
1916 if (isnanf(b)) return -1;
1917 if (!finitef(a) || !finitef(b)) {
1918 a = finitef(a) ? 0 : copysignf(1.0, a);
1919 b = finitef(b) ? 0 : copysignf(1.0, b);
1921 if (a > b) return 1;
1922 if (a == b) return 0;
1927 s4 builtin_fcmpg(float a, float b)
1929 if (isnanf(a)) return 1;
1930 if (isnanf(b)) return 1;
1931 if (!finitef(a) || !finitef(b)) {
1932 a = finitef(a) ? 0 : copysignf(1.0, a);
1933 b = finitef(b) ? 0 : copysignf(1.0, b);
1935 if (a > b) return 1;
1936 if (a == b) return 0;
1942 /************************* Functions for doubles ****************************/
1944 double builtin_dadd(double a, double b)
1946 if (isnan(a)) return longBitsToDouble(DBL_NAN);
1947 if (isnan(b)) return longBitsToDouble(DBL_NAN);
1949 if (finite(b)) return a + b;
1953 if (finite(b)) return a;
1955 if (copysign(1.0, a)==copysign(1.0, b)) return a;
1956 else return longBitsToDouble(DBL_NAN);
1962 double builtin_dsub(double a, double b)
1964 return builtin_dadd(a, builtin_dneg(b));
1968 double builtin_dmul(double a, double b)
1970 if (isnan(a)) return longBitsToDouble(DBL_NAN);
1971 if (isnan(b)) return longBitsToDouble(DBL_NAN);
1973 if (finite(b)) return a * b;
1975 if (a == 0) return longBitsToDouble(DBL_NAN);
1976 else return copysign(b, copysign(1.0, b) * a);
1981 if (b == 0) return longBitsToDouble(DBL_NAN);
1982 else return copysign(a, copysign(1.0, a) * b);
1985 return copysign(a, copysign(1.0, a) * copysign(1.0, b));
1991 double builtin_ddiv(double a, double b)
1999 return longBitsToDouble(DBL_NAN);
2001 return copysign(0.0, b);
2007 return longBitsToDouble(DBL_POSINF);
2009 return longBitsToDouble(DBL_NEGINF);
2012 return longBitsToDouble(DBL_NAN);
2015 /* if (finite(a) && finite(b)) { */
2020 /* return longBitsToDouble(DBL_POSINF); */
2021 /* else if (a < 0) */
2022 /* return longBitsToDouble(DBL_NEGINF); */
2026 /* keep compiler happy */
2031 double builtin_drem(double a, double b)
2037 double builtin_dneg(double a)
2039 if (isnan(a)) return a;
2041 if (finite(a)) return -a;
2042 else return copysign(a, -copysign(1.0, a));
2047 s4 builtin_dcmpl(double a, double b)
2049 if (isnan(a)) return -1;
2050 if (isnan(b)) return -1;
2051 if (!finite(a) || !finite(b)) {
2052 a = finite(a) ? 0 : copysign(1.0, a);
2053 b = finite(b) ? 0 : copysign(1.0, b);
2055 if (a > b) return 1;
2056 if (a == b) return 0;
2061 s4 builtin_dcmpg(double a, double b)
2063 if (isnan(a)) return 1;
2064 if (isnan(b)) return 1;
2065 if (!finite(a) || !finite(b)) {
2066 a = finite(a) ? 0 : copysign(1.0, a);
2067 b = finite(b) ? 0 : copysign(1.0, b);
2069 if (a > b) return 1;
2070 if (a == b) return 0;
2075 /*********************** Conversion operations ****************************/
2077 s8 builtin_i2l(s4 i)
2090 float builtin_i2f(s4 a)
2092 float f = (float) a;
2097 double builtin_i2d(s4 a)
2099 double d = (double) a;
2104 s4 builtin_l2i(s8 l)
2114 float builtin_l2f(s8 a)
2117 float f = (float) a;
2125 double builtin_l2d(s8 a)
2128 double d = (double) a;
2136 s4 builtin_f2i(float a)
2139 return builtin_d2i((double) a);
2148 if (a < (-2147483648))
2149 return (-2147483648);
2152 f = copysignf((float) 1.0, a);
2155 return (-2147483648); */
2159 s8 builtin_f2l(float a)
2162 return builtin_d2l((double) a);
2167 if (a > 9223372036854775807L)
2168 return 9223372036854775807L;
2169 if (a < (-9223372036854775808L))
2170 return (-9223372036854775808L);
2175 f = copysignf((float) 1.0, a);
2177 return 9223372036854775807L;
2178 return (-9223372036854775808L); */
2182 double builtin_f2d(float a)
2184 if (finitef(a)) return (double) a;
2187 return longBitsToDouble(DBL_NAN);
2189 return copysign(longBitsToDouble(DBL_POSINF), (double) copysignf(1.0, a) );
2194 s4 builtin_d2i(double a)
2199 if (a >= 2147483647)
2201 if (a <= (-2147483647-1))
2202 return (-2147483647-1);
2207 d = copysign(1.0, a);
2210 return (-2147483647-1);
2214 s8 builtin_d2l(double a)
2219 if (a >= 9223372036854775807LL)
2220 return 9223372036854775807LL;
2221 if (a <= (-9223372036854775807LL-1))
2222 return (-9223372036854775807LL-1);
2227 d = copysign(1.0, a);
2229 return 9223372036854775807LL;
2230 return (-9223372036854775807LL-1);
2234 float builtin_d2f(double a)
2240 return intBitsToFloat(FLT_NAN);
2242 return copysignf(intBitsToFloat(FLT_POSINF), (float) copysign(1.0, a));
2247 /* used to convert FLT_xxx defines into float values */
2249 inline float intBitsToFloat(s4 i)
2258 /* used to convert DBL_xxx defines into double values */
2260 inline float longBitsToDouble(s8 l)
2269 java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o)
2271 return (java_arrayheader *)
2272 Java_java_lang_VMObject_clone(0, 0, (java_lang_Cloneable *) o);
2276 s4 builtin_dummy(void)
2278 log_text("Internal error: builtin_dummy called (native function is missing)");
2281 /* keep the compiler happy */
2287 /* builtin_asm_get_exceptionptrptr *********************************************
2289 this is a wrapper for calls from asmpart
2291 *******************************************************************************/
2293 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2294 java_objectheader **builtin_asm_get_exceptionptrptr(void)
2296 return builtin_get_exceptionptrptr();
2301 methodinfo *builtin_asm_get_threadrootmethod(void)
2303 return *threadrootmethod;
2307 void *builtin_asm_get_stackframeinfo(void)
2309 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2310 return &THREADINFO->_stackframeinfo;
2312 /* XXX FIXME FOR OLD THREAD IMPL (jowenn) */
2314 return &_thread_nativestackframeinfo; /* no threading, at least no native*/
2319 stacktraceelement *builtin_stacktrace_copy(stacktraceelement **el,
2320 stacktraceelement *begin,
2321 stacktraceelement *end)
2323 /* stacktraceelement *el;*/
2326 /*printf ("begin: %p, end: %p, diff: %ld, size :%ld\n",begin,end,s,s*sizeof(stacktraceelement));*/
2327 *el=heap_allocate(sizeof(stacktraceelement)*(s+1), true, 0);
2329 *el=MNEW(stacktraceelement,s+1); /*GC*/
2331 memcpy(*el,begin,(end-begin)*sizeof(stacktraceelement));
2334 /* XXX change this if line numbers bigger than u2 are allowed, the */
2335 /* currently supported class file format does no allow that */
2337 (*el)[s].linenumber=-1; /* -1 can never be reched otherwise, since line numbers are only u2, so it is save to use that as flag */
2343 * These are local overrides for various environment variables in Emacs.
2344 * Please do not remove this and leave it at the end of the file, where
2345 * Emacs will automagically detect them.
2346 * ---------------------------------------------------------------------
2349 * indent-tabs-mode: t