X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fbuiltin.c;h=57918bdcaada8b461545d8ef80213210775ef5d2;hb=cc78025b4ac412a74a0535eb910578ec335122b4;hp=5c4a33419cb764b8ea3d20b2d80e30be94eb326e;hpb=4651daaa72bc09fd4f5e03c0cc33f48992583563;p=cacao.git diff --git a/src/vm/builtin.c b/src/vm/builtin.c index 5c4a33419..57918bdca 100644 --- a/src/vm/builtin.c +++ b/src/vm/builtin.c @@ -1,9 +1,9 @@ /* src/vm/builtin.c - functions for unsupported operations - Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates, - R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, - C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, - Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, + C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, + E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, + J. Wenninger, Institut f. Computersprachen - TU Wien This file is part of CACAO. @@ -19,16 +19,17 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. - Contact: cacao@complang.tuwien.ac.at + Contact: cacao@cacaojvm.org Authors: Reinhard Grafl Andreas Krall Mark Probst Changes: Christian Thalinger + Edwin Steiner Contains C functions for JavaVM Instructions that cannot be translated to machine language directly. Consequently, the @@ -36,23 +37,30 @@ calls instead of machine instructions, using the C calling convention. - $Id: builtin.c 2330 2005-04-21 22:41:57Z twisti $ + $Id: builtin.c 4690 2006-03-27 11:37:46Z twisti $ */ +#include "config.h" + #include #include #include #include -#include "config.h" +#include "vm/types.h" + #include "arch.h" -#include "types.h" +#include "md-abi.h" + +#include "fdlibm/fdlibm.h" + #include "mm/boehm.h" #include "mm/memory.h" #include "native/native.h" #include "native/include/java_lang_Cloneable.h" +#include "native/include/java_lang_Object.h" /* required by VMObject */ #include "native/include/java_lang_VMObject.h" #if defined(USE_THREADS) @@ -65,262 +73,250 @@ #endif #include "toolbox/logging.h" +#include "toolbox/util.h" #include "vm/builtin.h" +#include "vm/class.h" #include "vm/exceptions.h" #include "vm/global.h" #include "vm/initialize.h" #include "vm/loader.h" #include "vm/options.h" #include "vm/stringlocal.h" -#include "vm/tables.h" #include "vm/jit/asmpart.h" +#include "vm/jit/patcher.h" -#undef DEBUG /*define DEBUG 1*/ +/* include builtin tables *****************************************************/ -THREADSPECIFIC methodinfo* _threadrootmethod = NULL; -THREADSPECIFIC void *_thread_nativestackframeinfo = NULL; +#include "vm/builtintable.inc" -#if defined(USEBUILTINTABLE) +/* builtintable_init *********************************************************** -#if 0 -stdopdescriptor builtintable[] = { - { ICMD_LCMP, TYPE_LONG, TYPE_LONG, TYPE_INT, ICMD_BUILTIN2, - (functionptr) builtin_lcmp , SUPPORT_LONG && SUPPORT_LONG_CMP, false }, - { ICMD_LAND, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_land , SUPPORT_LONG && SUPPORT_LONG_LOGICAL, false }, - { ICMD_LOR, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_lor , SUPPORT_LONG && SUPPORT_LONG_LOGICAL, false }, - { ICMD_LXOR, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_lxor , SUPPORT_LONG && SUPPORT_LONG_LOGICAL, false }, - { ICMD_LSHL, TYPE_LONG, TYPE_INT, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_lshl , SUPPORT_LONG && SUPPORT_LONG_SHIFT, false }, - { ICMD_LSHR, TYPE_LONG, TYPE_INT, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_lshr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false }, - { ICMD_LUSHR, TYPE_LONG, TYPE_INT, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_lushr, SUPPORT_LONG && SUPPORT_LONG_SHIFT, false }, - { ICMD_LADD, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_ladd , SUPPORT_LONG && SUPPORT_LONG_ADD, false }, - { ICMD_LSUB, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_lsub , SUPPORT_LONG && SUPPORT_LONG_ADD, false }, - { ICMD_LNEG, TYPE_LONG, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1, - (functionptr) builtin_lneg, SUPPORT_LONG && SUPPORT_LONG_ADD, true }, - { ICMD_LMUL, TYPE_LONG, TYPE_LONG, TYPE_LONG, ICMD_BUILTIN2, - (functionptr) builtin_lmul , SUPPORT_LONG && SUPPORT_LONG_MUL, false }, - { ICMD_I2F, TYPE_INT, TYPE_VOID, TYPE_FLOAT, ICMD_BUILTIN1, - (functionptr) builtin_i2f, SUPPORT_FLOAT && SUPPORT_IFCVT, true }, - { ICMD_I2D, TYPE_INT, TYPE_VOID, TYPE_DOUBLE, ICMD_BUILTIN1, - (functionptr) builtin_i2d, SUPPORT_DOUBLE && SUPPORT_IFCVT, true }, - { ICMD_L2F, TYPE_LONG, TYPE_VOID, TYPE_FLOAT, ICMD_BUILTIN1, - (functionptr) builtin_l2f, SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT, true }, - { ICMD_L2D, TYPE_LONG, TYPE_VOID, TYPE_DOUBLE, ICMD_BUILTIN1, - (functionptr) builtin_l2d, SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT, true }, - { ICMD_F2L, TYPE_FLOAT, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1, - (functionptr) builtin_f2l, SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT, true }, - { ICMD_D2L, TYPE_DOUBLE, TYPE_VOID, TYPE_LONG, ICMD_BUILTIN1, - (functionptr) builtin_d2l, SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT, true }, - { ICMD_F2I, TYPE_FLOAT, TYPE_VOID, TYPE_INT, ICMD_BUILTIN1, - (functionptr) builtin_f2i, SUPPORT_FLOAT && SUPPORT_FICVT, true }, - { ICMD_D2I, TYPE_DOUBLE, TYPE_VOID, TYPE_INT, ICMD_BUILTIN1, - (functionptr) builtin_d2i, SUPPORT_DOUBLE && SUPPORT_FICVT, true }, - { 255, 0, 0, 0, 0, NULL, true, false }, -}; + Parse the descriptors of builtin functions and create the parsed + descriptors. -#endif +*******************************************************************************/ -static int builtintablelen; +static bool builtintable_init(void) +{ + descriptor_pool *descpool; + s4 dumpsize; + utf *descriptor; + s4 entries_internal; + s4 entries_automatic; + s4 i; -#endif /* USEBUILTINTABLE */ + /* mark start of dump memory area */ + dumpsize = dump_size(); -/***************************************************************************** - TABLE OF BUILTIN FUNCTIONS + /* create a new descriptor pool */ - This table lists the builtin functions which are used inside - BUILTIN* opcodes. + descpool = descriptor_pool_new(class_java_lang_Object); - The first part of the table (up to the 255-marker) lists the - opcodes which are automatically replaced in stack.c. + /* add some entries we need */ - The second part lists the builtin functions which are "manually" - used for BUILTIN* opcodes in parse.c and stack.c. + if (!descriptor_pool_add_class(descpool, utf_java_lang_Object)) + return false; -*****************************************************************************/ + if (!descriptor_pool_add_class(descpool, utf_java_lang_Class)) + return false; -builtin_descriptor builtin_desc[] = { -#if defined(USEBUILTINTABLE) - {ICMD_LCMP , BUILTIN_lcmp ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_INT , - SUPPORT_LONG && SUPPORT_LONG_CMP,false,"lcmp"}, - - {ICMD_LAND , BUILTIN_land ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_LOGICAL,false,"land"}, - {ICMD_LOR , BUILTIN_lor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_LOGICAL,false,"lor"}, - {ICMD_LXOR , BUILTIN_lxor ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_LOGICAL,false,"lxor"}, - - {ICMD_LSHL , BUILTIN_lshl ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshl"}, - {ICMD_LSHR , BUILTIN_lshr ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lshr"}, - {ICMD_LUSHR, BUILTIN_lushr,ICMD_BUILTIN2,TYPE_LONG ,TYPE_INT ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_SHIFT,false,"lushr"}, - - {ICMD_LADD , BUILTIN_ladd ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_ADD,false,"ladd"}, - {ICMD_LSUB , BUILTIN_lsub ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lsub"}, - {ICMD_LNEG , BUILTIN_lneg ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_ADD,false,"lneg"}, - {ICMD_LMUL , BUILTIN_lmul ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG , - SUPPORT_LONG && SUPPORT_LONG_MUL,false,"lmul"}, - - {ICMD_I2F , BUILTIN_i2f ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT , - SUPPORT_FLOAT && SUPPORT_IFCVT,true ,"i2f"}, - {ICMD_I2D , BUILTIN_i2d ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE, - SUPPORT_DOUBLE && SUPPORT_IFCVT,true ,"i2d"}, - {ICMD_L2F , BUILTIN_l2f ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_FLOAT , - SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_LONG_FCVT,true ,"l2f"}, - {ICMD_L2D , BUILTIN_l2d ,ICMD_BUILTIN1,TYPE_LONG ,TYPE_VOID ,TYPE_VOID ,TYPE_DOUBLE, - SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_LONG_FCVT,true ,"l2d"}, - {ICMD_F2L , BUILTIN_f2l ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG , - SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"f2l"}, - {ICMD_D2L , BUILTIN_d2l ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_LONG , - SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_LONG_ICVT,true ,"d2l"}, - {ICMD_F2I , BUILTIN_f2i ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_INT , - SUPPORT_FLOAT && SUPPORT_FICVT,true ,"f2i"}, - {ICMD_D2I , BUILTIN_d2i ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_INT , - SUPPORT_DOUBLE && SUPPORT_FICVT,true ,"d2i"}, - - { ICMD_FADD , BUILTIN_fadd , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fadd" }, - { ICMD_FSUB , BUILTIN_fsub , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fsub" }, - { ICMD_FMUL , BUILTIN_fmul , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fmul" }, - { ICMD_FDIV , BUILTIN_fdiv , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fdiv" }, - { ICMD_FNEG , BUILTIN_fneg , ICMD_BUILTIN1, TYPE_FLT, TYPE_VOID , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT, true, "fneg" }, - { ICMD_FCMPL, BUILTIN_fcmpl , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_INT, SUPPORT_FLOAT, true, "fcmpl" }, - { ICMD_FCMPG, BUILTIN_fcmpg , ICMD_BUILTIN2, TYPE_FLT, TYPE_FLT , TYPE_VOID , TYPE_INT, SUPPORT_FLOAT, true, "fcmpg" }, - - { ICMD_DADD , BUILTIN_dadd , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dadd" }, - { ICMD_DSUB , BUILTIN_dsub , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dsub" }, - { ICMD_DMUL , BUILTIN_dmul , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dmul" }, - { ICMD_DDIV , BUILTIN_ddiv , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "ddiv" }, - { ICMD_DNEG , BUILTIN_dneg , ICMD_BUILTIN1, TYPE_DBL, TYPE_VOID , TYPE_VOID , TYPE_DBL, SUPPORT_DOUBLE, true, "dneg" }, - { ICMD_DCMPL, BUILTIN_dcmpl , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_INT, SUPPORT_DOUBLE, true, "dcmpl" }, - { ICMD_DCMPG, BUILTIN_dcmpg , ICMD_BUILTIN2, TYPE_DBL, TYPE_DBL , TYPE_VOID , TYPE_INT, SUPPORT_DOUBLE, true, "dcmpg" }, - - { ICMD_F2D, BUILTIN_f2d , ICMD_BUILTIN1, TYPE_FLT, TYPE_VOID , TYPE_VOID , TYPE_DBL, SUPPORT_FLOAT && SUPPORT_DOUBLE, true, "f2d" }, - { ICMD_D2F, BUILTIN_d2f , ICMD_BUILTIN1, TYPE_DBL, TYPE_VOID , TYPE_VOID , TYPE_FLT, SUPPORT_FLOAT && SUPPORT_DOUBLE, true, "d2f" }, -#endif + /* calculate table entries statically */ - /* this record marks the end of the automatically replaced opcodes */ - {255,NULL,0,0,0,0,0,0,0,""}, + entries_internal = + sizeof(builtintable_internal) / sizeof(builtintable_entry); - /* the following functions are not replaced automatically */ - -#if defined(__ALPHA__) - {255, BUILTIN_f2l ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,0,0,"f2l"}, - {255, BUILTIN_d2l ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_LONG ,0,0,"d2l"}, - {255, BUILTIN_f2i ,ICMD_BUILTIN1,TYPE_FLOAT ,TYPE_VOID ,TYPE_VOID ,TYPE_INT ,0,0,"f2i"}, - {255, BUILTIN_d2i ,ICMD_BUILTIN1,TYPE_DOUBLE,TYPE_VOID ,TYPE_VOID ,TYPE_INT ,0,0,"d2i"}, -#endif + entries_automatic = + sizeof(builtintable_automatic) / sizeof(builtintable_entry) + - 1; /* last filler entry (comment see builtintable.inc) */ - {255,BUILTIN_instanceof ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_INT ,0,0,"instanceof"}, - {255,BUILTIN_arrayinstanceof ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_INT ,0,0,"arrayinstanceof"}, - {255,BUILTIN_checkarraycast ,ICMD_BUILTIN2,TYPE_ADR ,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,0,0,"checkarraycast"}, - {255,BUILTIN_aastore ,ICMD_BUILTIN3,TYPE_ADR ,TYPE_INT ,TYPE_ADR ,TYPE_VOID ,0,0,"aastore"}, - {255,BUILTIN_new ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"new"}, - {255,BUILTIN_newarray ,ICMD_BUILTIN2,TYPE_INT ,TYPE_ADR ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray"}, - {255,BUILTIN_newarray_boolean,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_boolean"}, - {255,BUILTIN_newarray_char ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_char"}, - {255,BUILTIN_newarray_float ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_float"}, - {255,BUILTIN_newarray_double ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_double"}, - {255,BUILTIN_newarray_byte ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_byte"}, - {255,BUILTIN_newarray_short ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_short"}, - {255,BUILTIN_newarray_int ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_int"}, - {255,BUILTIN_newarray_long ,ICMD_BUILTIN1,TYPE_INT ,TYPE_VOID ,TYPE_VOID ,TYPE_ADR ,0,0,"newarray_long"}, -#if defined(USE_THREADS) - {255,BUILTIN_monitorenter ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorenter"}, - {255,BUILTIN_monitorexit ,ICMD_BUILTIN1,TYPE_ADR ,TYPE_VOID ,TYPE_VOID ,TYPE_VOID ,0,0,"monitorexit"}, -#endif -#if !SUPPORT_DIVISION - {255,BUILTIN_idiv ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"idiv"}, - {255,BUILTIN_irem ,ICMD_BUILTIN2,TYPE_INT ,TYPE_INT ,TYPE_VOID ,TYPE_INT ,0,0,"irem"}, -#endif -#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) - {255,BUILTIN_ldiv ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"ldiv"}, - {255,BUILTIN_lrem ,ICMD_BUILTIN2,TYPE_LONG ,TYPE_LONG ,TYPE_VOID ,TYPE_LONG ,0,0,"lrem"}, -#endif - {255,BUILTIN_frem ,ICMD_BUILTIN2,TYPE_FLOAT ,TYPE_FLOAT ,TYPE_VOID ,TYPE_FLOAT ,0,0,"frem"}, - {255,BUILTIN_drem ,ICMD_BUILTIN2,TYPE_DOUBLE,TYPE_DOUBLE,TYPE_VOID ,TYPE_DOUBLE,0,0,"drem"}, + /* first add all descriptors to the pool */ + for (i = 0; i < entries_internal; i++) { + /* create a utf8 string from descriptor */ -#if defined(__X86_64__) || defined(__I386__) - /* assembler code patching functions */ + descriptor = utf_new_char(builtintable_internal[i].descriptor); - { 255, asm_wrapper_patcher_BUILTIN_new , ICMD_BUILTIN1, TYPE_ADR , TYPE_VOID , TYPE_VOID , TYPE_ADR , 0, 0, "new (calling asm_wrapper_patcher_builtin_new)" }, -#endif -#if defined(__X86_64__) - { 255, asm_wrapper_patcher_BUILTIN_newarray , ICMD_BUILTIN1, TYPE_ADR , TYPE_VOID , TYPE_VOID , TYPE_ADR , 0, 0, "newarray (calling asm_wrapper_patcher_builtin_newarray)" }, - { 255, asm_wrapper_patcher_BUILTIN_checkarraycast , ICMD_BUILTIN2, TYPE_ADR , TYPE_ADR , TYPE_VOID , TYPE_VOID , 0, 0, "checkarraycast (calling asm_wrapper_patcher_builtin_checkarraycast)" }, - { 255, asm_wrapper_patcher_BUILTIN_arrayinstanceof, ICMD_BUILTIN2, TYPE_ADR , TYPE_ADR , TYPE_VOID , TYPE_INT , 0, 0, "arrayinstanceof (calling asm_wrapper_patcher_builtin_arrayinstanceof)" }, -#endif + if (!descriptor_pool_add(descpool, descriptor, NULL)) { + /* release dump area */ + + dump_release(dumpsize); + + return false; + } + } + + for (i = 0; i < entries_automatic; i++) { + /* create a utf8 string from descriptor */ + descriptor = utf_new_char(builtintable_automatic[i].descriptor); - /* this record marks the end of the list */ + if (!descriptor_pool_add(descpool, descriptor, NULL)) { + /* release dump area */ - { 0, NULL, 0, 0, 0, 0, 0, 0, 0, "" } -}; + dump_release(dumpsize); + return false; + } + } + + /* create the class reference table */ + + (void) descriptor_pool_create_classrefs(descpool, NULL); + + /* allocate space for the parsed descriptors */ + + descriptor_pool_alloc_parsed_descriptors(descpool); + + /* now parse all descriptors */ + + for (i = 0; i < entries_internal; i++) { + /* create a utf8 string from descriptor */ + + descriptor = utf_new_char(builtintable_internal[i].descriptor); + + /* parse the descriptor, builtin is always static (no `this' pointer) */ + + builtintable_internal[i].md = + descriptor_pool_parse_method_descriptor(descpool, descriptor, + ACC_STATIC, NULL); + } + + for (i = 0; i < entries_automatic; i++) { + /* create a utf8 string from descriptor */ + + descriptor = utf_new_char(builtintable_automatic[i].descriptor); + + /* parse the descriptor, builtin is always static (no `this' pointer) */ + + builtintable_automatic[i].md = + descriptor_pool_parse_method_descriptor(descpool, descriptor, + ACC_STATIC, NULL); + } + + /* release dump area */ + + dump_release(dumpsize); + + return true; +} + + +/* builtintable_comparator ***************************************************** + + qsort comparator for the automatic builtin table. -#if defined(USEBUILTINTABLE) +*******************************************************************************/ -static int stdopcompare(const void *a, const void *b) +static int builtintable_comparator(const void *a, const void *b) { - builtin_descriptor *o1 = (builtin_descriptor *) a; - builtin_descriptor *o2 = (builtin_descriptor *) b; - if (!o1->supported && o2->supported) - return -1; - if (o1->supported && !o2->supported) - return 1; - return (o1->opcode < o2->opcode) ? -1 : (o1->opcode > o2->opcode); + builtintable_entry *bte1; + builtintable_entry *bte2; + + bte1 = (builtintable_entry *) a; + bte2 = (builtintable_entry *) b; + + return (bte1->opcode < bte2->opcode) ? -1 : (bte1->opcode > bte2->opcode); +} + + +/* builtintable_sort_automatic ************************************************* + + Sorts the automatic builtin table. + +*******************************************************************************/ + +static void builtintable_sort_automatic(void) +{ + s4 entries; + + /* calculate table size statically (`- 1' comment see builtintable.inc) */ + + entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1; + + qsort(builtintable_automatic, entries, sizeof(builtintable_entry), + builtintable_comparator); +} + + +/* builtin_init **************************************************************** + + XXX + +*******************************************************************************/ + +bool builtin_init(void) +{ + /* initialize the builtin tables */ + + if (!builtintable_init()) + return false; + + /* sort builtin tables */ + + builtintable_sort_automatic(); + + return true; } -void sort_builtintable(void) +/* builtintable_get_internal *************************************************** + + Finds an entry in the builtintable for internal functions and + returns the a pointer to the structure. + +*******************************************************************************/ + +builtintable_entry *builtintable_get_internal(functionptr fp) { - int len; + s4 i; - len = 0; - while (builtin_desc[len].opcode != 255) len++; - qsort(builtin_desc, len, sizeof(builtin_descriptor), stdopcompare); + for (i = 0; builtintable_internal[i].fp != NULL; i++) { + if (builtintable_internal[i].fp == fp) + return &builtintable_internal[i]; + } - for (--len; len>=0 && builtin_desc[len].supported; len--); - builtintablelen = ++len; + return NULL; } -builtin_descriptor *find_builtin(int icmd) +/* builtintable_get_automatic ************************************************** + + Finds an entry in the builtintable for functions which are replaced + automatically and returns the a pointer to the structure. + +*******************************************************************************/ + +builtintable_entry *builtintable_get_automatic(s4 opcode) { - builtin_descriptor *first = builtin_desc; - builtin_descriptor *last = builtin_desc + builtintablelen; - int len = last - first; - int half; - builtin_descriptor *middle; + builtintable_entry *first; + builtintable_entry *last; + builtintable_entry *middle; + s4 half; + s4 entries; + + /* calculate table size statically (`- 1' comment see builtintable.inc) */ + + entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1; - while (len > 0) { - half = len / 2; + first = builtintable_automatic; + last = builtintable_automatic + entries; + + while (entries > 0) { + half = entries / 2; middle = first + half; - if (middle->opcode < icmd) { + + if (middle->opcode < opcode) { first = middle + 1; - len -= half + 1; + entries -= half + 1; } else - len = half; + entries = half; } - return first != last ? first : NULL; -} -#endif /* defined(USEBUILTINTABLE) */ + return (first != last ? first : NULL); +} /***************************************************************************** @@ -345,14 +341,16 @@ s4 builtin_isanysubclass(classinfo *sub, classinfo *super) if (sub == super) return 1; - if (super->flags & ACC_INTERFACE) - return (sub->vftbl->interfacetablelength > super->index) && + if (super->flags & ACC_INTERFACE) { + res = (sub->vftbl->interfacetablelength > super->index) && (sub->vftbl->interfacetable[-super->index] != NULL); - asm_getclassvalues_atomic(super->vftbl, sub->vftbl, &classvalues); + } else { + ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues); - res = (u4) (classvalues.sub_baseval - classvalues.super_baseval) <= - (u4) classvalues.super_diffval; + res = (u4) (classvalues.sub_baseval - classvalues.super_baseval) <= + (u4) classvalues.super_diffval; + } return res; } @@ -367,15 +365,16 @@ s4 builtin_isanysubclass_vftbl(vftbl_t *sub, vftbl_t *super) if (sub == super) return 1; - asm_getclassvalues_atomic(super, sub, &classvalues); + ASM_GETCLASSVALUES_ATOMIC(super, sub, &classvalues); - if ((base = classvalues.super_baseval) <= 0) + if ((base = classvalues.super_baseval) <= 0) { /* super is an interface */ res = (sub->interfacetablelength > -base) && (sub->interfacetable[base] != NULL); - else + } else { res = (u4) (classvalues.sub_baseval - classvalues.super_baseval) <= (u4) classvalues.super_diffval; + } return res; } @@ -391,12 +390,8 @@ s4 builtin_isanysubclass_vftbl(vftbl_t *sub, vftbl_t *super) *****************************************************************************/ -/* XXX should use vftbl */ s4 builtin_instanceof(java_objectheader *obj, classinfo *class) { -#ifdef DEBUG - log_text ("builtin_instanceof called"); -#endif if (!obj) return 0; @@ -412,89 +407,96 @@ s4 builtin_instanceof(java_objectheader *obj, classinfo *class) ****************************************************************************/ -/* XXX should use vftbl */ s4 builtin_checkcast(java_objectheader *obj, classinfo *class) { -#ifdef DEBUG - log_text("builtin_checkcast called"); -#endif - if (obj == NULL) return 1; + if (builtin_isanysubclass(obj->vftbl->class, class)) return 1; -#if DEBUG - printf("#### checkcast failed "); - utf_display(obj->vftbl->class->name); - printf(" -> "); - utf_display(class->name); - printf("\n"); -#endif - return 0; } -/*********** internal function: builtin_descriptorscompatible ****************** +/* builtin_descriptorscompatible *********************************************** - Checks if two array type descriptors are assignment compatible - Return value: 1 ... target = desc is possible - 0 ... otherwise + Checks if two array type descriptors are assignment compatible + + Return value: 1 ... target = desc is possible + 0 ... otherwise -******************************************************************************/ +*******************************************************************************/ -static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target) +static s4 builtin_descriptorscompatible(arraydescriptor *desc, + arraydescriptor *target) { - if (desc==target) return 1; - if (desc->arraytype != target->arraytype) return 0; - if (desc->arraytype != ARRAYTYPE_OBJECT) return 1; + if (desc == target) + return 1; + + if (desc->arraytype != target->arraytype) + return 0; + + if (desc->arraytype != ARRAYTYPE_OBJECT) + return 1; /* {both arrays are arrays of references} */ + if (desc->dimension == target->dimension) { - /* an array which contains elements of interface types is allowed to be casted to Object (JOWENN)*/ - if ( (desc->elementvftbl->baseval<0) && (target->elementvftbl->baseval==1) ) return 1; - return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl); + /* an array which contains elements of interface types is + allowed to be casted to Object (JOWENN)*/ + + if ((desc->elementvftbl->baseval < 0) && + (target->elementvftbl->baseval == 1)) + return 1; + + return builtin_isanysubclass_vftbl(desc->elementvftbl, + target->elementvftbl); } - if (desc->dimension < target->dimension) return 0; + + if (desc->dimension < target->dimension) + return 0; /* {desc has higher dimension than target} */ - return builtin_isanysubclass_vftbl(pseudo_class_Arraystub->vftbl, target->elementvftbl); + + return builtin_isanysubclass_vftbl(pseudo_class_Arraystub->vftbl, + target->elementvftbl); } -/******************** function: builtin_checkarraycast *********************** +/* builtin_arraycheckcast ****************************************************** - Checks if an object is really a subtype of the requested array type. - The object has to be an array to begin with. For simple arrays (int, short, - double, etc.) the types have to match exactly. - For arrays of objects, the type of elements in the array has to be a - subtype (or the same type) of the requested element type. For arrays of - arrays (which in turn can again be arrays of arrays), the types at the - lowest level have to satisfy the corresponding sub class relation. - - Return value: 1 ... cast is possible - 0 ... otherwise + Checks if an object is really a subtype of the requested array + type. The object has to be an array to begin with. For simple + arrays (int, short, double, etc.) the types have to match exactly. + For arrays of objects, the type of elements in the array has to be + a subtype (or the same type) of the requested element type. For + arrays of arrays (which in turn can again be arrays of arrays), the + types at the lowest level have to satisfy the corresponding sub + class relation. - ATTENTION: a cast with a NULL pointer is always possible. - -*****************************************************************************/ +*******************************************************************************/ -s4 builtin_checkarraycast(java_objectheader *o, vftbl_t *target) +s4 builtin_arraycheckcast(java_objectheader *o, classinfo *targetclass) { arraydescriptor *desc; - - if (!o) return 1; - if ((desc = o->vftbl->arraydesc) == NULL) return 0; - return builtin_descriptorscompatible(desc, target->arraydesc); + if (!o) + return 1; + + if ((desc = o->vftbl->arraydesc) == NULL) + return 0; + + return builtin_descriptorscompatible(desc, targetclass->vftbl->arraydesc); } -s4 builtin_arrayinstanceof(java_objectheader *obj, vftbl_t *target) +s4 builtin_arrayinstanceof(java_objectheader *o, classinfo *targetclass) { - if (!obj) return 1; - return builtin_checkarraycast(obj, target); + if (!o) + return 0; + + return builtin_arraycheckcast(o, targetclass); } @@ -502,15 +504,39 @@ s4 builtin_arrayinstanceof(java_objectheader *obj, vftbl_t *target) ******************************************************************************/ +#if !defined(NDEBUG) java_objectheader *builtin_throw_exception(java_objectheader *xptr) { + java_lang_Throwable *t; + char *logtext; + s4 logtextlen; + s4 dumpsize; + if (opt_verbose) { - char logtext[MAXLOGTEXT]; - sprintf(logtext, "Builtin exception thrown: "); + t = (java_lang_Throwable *) xptr; + + /* calculate message length */ - if (xptr) { - java_lang_Throwable *t = (java_lang_Throwable *) xptr; + logtextlen = strlen("Builtin exception thrown: ") + strlen("0"); + if (t) { + logtextlen += + utf_strlen(xptr->vftbl->class->name) + + strlen(": ") + + javastring_strlen(t->detailMessage); + + } else + logtextlen += strlen("(nil)"); + + /* allocate memory */ + + dumpsize = dump_size(); + + logtext = DMNEW(char, logtextlen); + + strcpy(logtext, "Builtin exception thrown: "); + + if (t) { utf_sprint_classname(logtext + strlen(logtext), xptr->vftbl->class->name); @@ -518,85 +544,94 @@ java_objectheader *builtin_throw_exception(java_objectheader *xptr) char *buf; buf = javastring_tochar((java_objectheader *) t->detailMessage); - sprintf(logtext + strlen(logtext), ": %s", buf); + strcat(logtext, ": "); + strcat(logtext, buf); MFREE(buf, char, strlen(buf)); } } else { - sprintf(logtext + strlen(logtext), "Error: "); + strcat(logtext, "(nil)"); } log_text(logtext); + + /* release memory */ + + dump_release(dumpsize); } *exceptionptr = xptr; return xptr; } +#endif /* !defined(NDEBUG) */ +/* builtin_canstore ************************************************************ -/******************* function: builtin_canstore ******************************* + Checks, if an object can be stored in an array. - Checks, if an object can be stored in an array. - Return value: 1 ... possible - 0 ... otherwise + Return value: 1 ... possible + 0 ... otherwise -******************************************************************************/ +*******************************************************************************/ -s4 builtin_canstore (java_objectarray *a, java_objectheader *o) +s4 builtin_canstore(java_objectarray *oa, java_objectheader *o) { arraydescriptor *desc; arraydescriptor *valuedesc; - vftbl_t *componentvftbl; - vftbl_t *valuevftbl; - int dim_m1; - int base; - castinfo classvalues; - - if (!o) return 1; + vftbl_t *componentvftbl; + vftbl_t *valuevftbl; + s4 base; + castinfo classvalues; + + if (!o) + return 1; /* The following is guaranteed (by verifier checks): * - * *) a->...vftbl->arraydesc != NULL - * *) a->...vftbl->arraydesc->componentvftbl != NULL + * *) oa->...vftbl->arraydesc != NULL + * *) oa->...vftbl->arraydesc->componentvftbl != NULL * *) o->vftbl is not an interface vftbl */ - desc = a->header.objheader.vftbl->arraydesc; - componentvftbl = desc->componentvftbl; - valuevftbl = o->vftbl; + desc = oa->header.objheader.vftbl->arraydesc; + componentvftbl = desc->componentvftbl; + valuevftbl = o->vftbl; - if ((dim_m1 = desc->dimension - 1) == 0) { + if ((desc->dimension - 1) == 0) { s4 res; - /* {a is a one-dimensional array} */ - /* {a is an array of references} */ + /* {oa is a one-dimensional array} */ + /* {oa is an array of references} */ if (valuevftbl == componentvftbl) return 1; - asm_getclassvalues_atomic(componentvftbl, valuevftbl, &classvalues); + ASM_GETCLASSVALUES_ATOMIC(componentvftbl, valuevftbl, &classvalues); if ((base = classvalues.super_baseval) <= 0) /* an array of interface references */ return (valuevftbl->interfacetablelength > -base && valuevftbl->interfacetable[base] != NULL); - res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval) - <= (unsigned) classvalues.super_diffval; + res = ((unsigned) (classvalues.sub_baseval - classvalues.super_baseval) + <= (unsigned) classvalues.super_diffval); return res; - } - /* {a has dimension > 1} */ + } + + /* {oa has dimension > 1} */ /* {componentvftbl->arraydesc != NULL} */ /* check if o is an array */ + if ((valuedesc = valuevftbl->arraydesc) == NULL) return 0; + /* {o is an array} */ - return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc); + return builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc); } @@ -629,7 +664,7 @@ s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o) if (valuevftbl == elementvftbl) return 1; - asm_getclassvalues_atomic(elementvftbl, valuevftbl, &classvalues); + ASM_GETCLASSVALUES_ATOMIC(elementvftbl, valuevftbl, &classvalues); if ((base = classvalues.super_baseval) <= 0) /* an array of interface references */ @@ -671,7 +706,7 @@ s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o) if (valuevftbl == elementvftbl) return 1; - asm_getclassvalues_atomic(elementvftbl, valuevftbl, &classvalues); + ASM_GETCLASSVALUES_ATOMIC(elementvftbl, valuevftbl, &classvalues); res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval) <= (unsigned) classvalues.super_diffval; @@ -694,17 +729,29 @@ java_objectheader *builtin_new(classinfo *c) java_objectheader *o; /* is the class loaded */ - /*utf_fprint(stderr,c->name);fprintf(stderr,"\n");*/ - assert(c->loaded); + + assert(c->state & CLASS_LOADED); + + /* check if we can instantiate this class */ + + if (c->flags & ACC_ABSTRACT) { + *exceptionptr = + new_exception_utfmessage(string_java_lang_InstantiationError, + c->name); + return NULL; + } /* is the class linked */ - if (!c->linked) + + if (!(c->state & CLASS_LINKED)) if (!link_class(c)) return NULL; - if (!c->initialized) { + if (!(c->state & CLASS_INITIALIZED)) { +#if !defined(NDEBUG) if (initverbose) log_message_class("Initialize class (from builtin_new): ", c); +#endif if (!initialize_class(c)) return NULL; @@ -715,8 +762,6 @@ java_objectheader *builtin_new(classinfo *c) if (!o) return NULL; - MSET(o, 0, u1, c->instancesize); - o->vftbl = c->vftbl; #if defined(USE_THREADS) && defined(NATIVE_THREADS) @@ -729,29 +774,27 @@ java_objectheader *builtin_new(classinfo *c) /* builtin_newarray ************************************************************ - Creates an array with the given vftbl on the heap. + Creates an array with the given vftbl on the heap. This function + takes as class argument an array class. Return value: pointer to the array or NULL if no memory is available - CAUTION: The given vftbl must be the vftbl of the *array* class, - not of the element class. - *******************************************************************************/ -java_arrayheader *builtin_newarray(s4 size, vftbl_t *arrayvftbl) +java_arrayheader *builtin_newarray(s4 size, classinfo *arrayclass) { + arraydescriptor *desc; + s4 dataoffset; + s4 componentsize; + s4 actualsize; java_arrayheader *a; - arraydescriptor *desc; - s4 dataoffset; - s4 componentsize; - s4 actualsize; - desc = arrayvftbl->arraydesc; - dataoffset = desc->dataoffset; + desc = arrayclass->vftbl->arraydesc; + dataoffset = desc->dataoffset; componentsize = desc->componentsize; if (size < 0) { - *exceptionptr = new_negativearraysizeexception(); + exceptions_throw_negativearraysizeexception(); return NULL; } @@ -767,9 +810,7 @@ java_arrayheader *builtin_newarray(s4 size, vftbl_t *arrayvftbl) if (!a) return NULL; - MSET(a, 0, u1, actualsize); - - a->objheader.vftbl = arrayvftbl; + a->objheader.vftbl = arrayclass->vftbl; #if defined(USE_THREADS) && defined(NATIVE_THREADS) initObjectLock(&a->objheader); @@ -790,159 +831,161 @@ java_arrayheader *builtin_newarray(s4 size, vftbl_t *arrayvftbl) *******************************************************************************/ -java_objectarray *builtin_anewarray(s4 size, classinfo *component) +java_objectarray *builtin_anewarray(s4 size, classinfo *componentclass) { - classinfo *c; + classinfo *arrayclass; /* is class loaded */ - assert(component->loaded); + + assert(componentclass->state & CLASS_LOADED); /* is class linked */ - if (!component->linked) - if (!link_class(component)) + + if (!(componentclass->state & CLASS_LINKED)) + if (!link_class(componentclass)) return NULL; - c = class_array_of(component, true); + arrayclass = class_array_of(componentclass, true); - if (!c) + if (!arrayclass) return NULL; - return (java_objectarray *) builtin_newarray(size, c->vftbl); + return (java_objectarray *) builtin_newarray(size, arrayclass); } -/* builtin_newarray_int ******************************************************** - - Creates an array of 32 bit Integers on the heap. +/* builtin_newarray_boolean **************************************************** + Creates an array of bytes on the heap. The array is designated as + an array of booleans (important for casts) + Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_intarray *builtin_newarray_int(s4 size) +java_booleanarray *builtin_newarray_boolean(s4 size) { - return (java_intarray *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayvftbl); + return (java_booleanarray *) + builtin_newarray(size, + primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass); } -/* builtin_newarray_long ******************************************************* +/* builtin_newarray_byte ******************************************************* - Creates an array of 64 bit Integers on the heap. + Creates an array of 8 bit Integers on the heap. Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_longarray *builtin_newarray_long(s4 size) +java_bytearray *builtin_newarray_byte(s4 size) { - return (java_longarray *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayvftbl); + return (java_bytearray *) + builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayclass); } -/* builtin_newarray_float ****************************************************** +/* builtin_newarray_char ******************************************************* - Creates an array of 32 bit IEEE floats on the heap. + Creates an array of characters on the heap. Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_floatarray *builtin_newarray_float(s4 size) +java_chararray *builtin_newarray_char(s4 size) { - return (java_floatarray *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl); + return (java_chararray *) + builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayclass); } -/* builtin_newarray_double ***************************************************** +/* builtin_newarray_short ****************************************************** - Creates an array of 64 bit IEEE floats on the heap. + Creates an array of 16 bit Integers on the heap. Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_doublearray *builtin_newarray_double(s4 size) +java_shortarray *builtin_newarray_short(s4 size) { - return (java_doublearray *) - builtin_newarray(size, - primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl); + return (java_shortarray *) + builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayclass); } -/* builtin_newarray_byte ******************************************************* +/* builtin_newarray_int ******************************************************** - Creates an array of 8 bit Integers on the heap. + Creates an array of 32 bit Integers on the heap. Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_bytearray *builtin_newarray_byte(s4 size) +java_intarray *builtin_newarray_int(s4 size) { - return (java_bytearray *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl); + return (java_intarray *) + builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayclass); } -/* builtin_newarray_char ******************************************************* +/* builtin_newarray_long ******************************************************* - Creates an array of characters on the heap. + Creates an array of 64 bit Integers on the heap. Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_chararray *builtin_newarray_char(s4 size) +java_longarray *builtin_newarray_long(s4 size) { - return (java_chararray *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl); + return (java_longarray *) + builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayclass); } -/* builtin_newarray_short ****************************************************** +/* builtin_newarray_float ****************************************************** - Creates an array of 16 bit Integers on the heap. + Creates an array of 32 bit IEEE floats on the heap. Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_shortarray *builtin_newarray_short(s4 size) +java_floatarray *builtin_newarray_float(s4 size) { - return (java_shortarray *) - builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl); + return (java_floatarray *) + builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass); } -/* builtin_newarray_boolean **************************************************** +/* builtin_newarray_double ***************************************************** + + Creates an array of 64 bit IEEE floats on the heap. - Creates an array of bytes on the heap. The array is designated as - an array of booleans (important for casts) - Return value: pointer to the array or NULL if no memory is available *******************************************************************************/ -java_booleanarray *builtin_newarray_boolean(s4 size) +java_doublearray *builtin_newarray_double(s4 size) { - return (java_booleanarray *) + return (java_doublearray *) builtin_newarray(size, - primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl); + primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass); } -/* builtin_multianewarray ****************************************************** +/* builtin_multianewarray_intern *********************************************** Creates a multi-dimensional array on the heap. The dimensions are passed in an array of longs. @@ -957,16 +1000,19 @@ java_booleanarray *builtin_newarray_boolean(s4 size) ******************************************************************************/ -java_arrayheader *builtin_multianewarray(int n, vftbl_t *arrayvftbl, long *dims) +static java_arrayheader *builtin_multianewarray_intern(int n, + classinfo *arrayclass, + long *dims) { - s4 size, i; + s4 size; java_arrayheader *a; - vftbl_t *componentvftbl; + classinfo *componentclass; + s4 i; /* create this dimension */ size = (s4) dims[0]; - a = builtin_newarray(size, arrayvftbl); + a = builtin_newarray(size, arrayclass); if (!a) return NULL; @@ -976,19 +1022,23 @@ java_arrayheader *builtin_multianewarray(int n, vftbl_t *arrayvftbl, long *dims) if (!--n) return a; - /* get the vftbl of the components to create */ + /* get the class of the components to create */ - componentvftbl = arrayvftbl->arraydesc->componentvftbl; + componentclass = arrayclass->vftbl->arraydesc->componentvftbl->class; - /* The verifier guarantees this. */ - /* if (!componentvftbl) */ - /* panic ("multianewarray with too many dimensions"); */ + /* The verifier guarantees that the dimension count is in the range. */ /* create the component arrays */ for (i = 0; i < size; i++) { - java_arrayheader *ea = - builtin_multianewarray(n, componentvftbl, dims + 1); + java_arrayheader *ea = +#if defined(__MIPS__) && (SIZEOF_VOID_P == 4) + /* we save an s4 to a s8 slot, 8-byte aligned */ + + builtin_multianewarray_intern(n, componentclass, dims + 2); +#else + builtin_multianewarray_intern(n, componentclass, dims + 1); +#endif if (!ea) return NULL; @@ -1000,6 +1050,41 @@ java_arrayheader *builtin_multianewarray(int n, vftbl_t *arrayvftbl, long *dims) } +/* builtin_multianewarray ****************************************************** + + Wrapper for builtin_multianewarray_intern which checks all + dimensions before we start allocating. + +******************************************************************************/ + +java_arrayheader *builtin_multianewarray(int n, classinfo *arrayclass, + long *dims) +{ + s4 i; + s4 size; + + /* check all dimensions before doing anything */ + + for (i = 0; i < n; i++) { +#if defined(__MIPS__) && (SIZEOF_VOID_P == 4) + /* we save an s4 to a s8 slot, 8-byte aligned */ + size = (s4) dims[i * 2]; +#else + size = (s4) dims[i]; +#endif + + if (size < 0) { + exceptions_throw_negativearraysizeexception(); + return NULL; + } + } + + /* now call the real function */ + + return builtin_multianewarray_intern(n, arrayclass, dims); +} + + /***************************************************************************** METHOD LOGGING @@ -1008,312 +1093,575 @@ java_arrayheader *builtin_multianewarray(int n, vftbl_t *arrayvftbl, long *dims) *****************************************************************************/ -u4 methodindent = 0; +#if !defined(NDEBUG) +static s4 methodindent = 0; +static u4 callcount = 0; java_objectheader *builtin_trace_exception(java_objectheader *xptr, methodinfo *m, void *pos, - s4 line, - s4 noindent) + s4 indent) { - char logtext[MAXLOGTEXT]; - - if (!noindent) { - if (methodindent) - methodindent--; + char *logtext; + s4 logtextlen; + s4 dumpsize; + codeinfo *code; + + if (opt_verbosecall && indent) + methodindent--; + + /* calculate message length */ + + if (xptr) { + logtextlen = + strlen("Exception ") + + utf_strlen(xptr->vftbl->class->name); + + } else { + logtextlen = strlen("Some Throwable"); + } + + logtextlen += strlen(" thrown in "); + + if (m) { + logtextlen += + utf_strlen(m->class->name) + + strlen(".") + + utf_strlen(m->name) + + utf_strlen(m->descriptor) + + strlen("(NOSYNC,NATIVE"); + +#if SIZEOF_VOID_P == 8 + logtextlen += + strlen(")(0x123456789abcdef0) at position 0x123456789abcdef0 ("); +#else + logtextlen += strlen(")(0x12345678) at position 0x12345678 ("); +#endif + + if (m->class->sourcefile == NULL) + logtextlen += strlen(""); else - log_text("WARNING: unmatched methodindent--"); + logtextlen += utf_strlen(m->class->sourcefile); + + logtextlen += strlen(":65536)"); + + } else + logtextlen += strlen("call_java_method"); + + logtextlen += strlen("0"); + + /* allocate memory */ + + dumpsize = dump_size(); + + logtext = DMNEW(char, logtextlen); + + if (xptr) { + strcpy(logtext, "Exception "); + utf_strcat_classname(logtext, xptr->vftbl->class->name); + + } else { + strcpy(logtext, "Some Throwable"); } - if (opt_verbose || runverbose || verboseexception) { - if (xptr) { - sprintf(logtext,"Exception "); - utf_sprint_classname(logtext+strlen(logtext), xptr->vftbl->class->name); - } else { - sprintf(logtext,"Some Throwable"); - } - sprintf(logtext+strlen(logtext), " thrown in "); + strcat(logtext, " thrown in "); - if (m) { - utf_sprint_classname(logtext+strlen(logtext), m->class->name); - sprintf(logtext+strlen(logtext), "."); - utf_sprint(logtext+strlen(logtext), m->name); - if (m->flags & ACC_SYNCHRONIZED) { - sprintf(logtext+strlen(logtext), "(SYNC"); + if (m) { + utf_strcat_classname(logtext, m->class->name); + strcat(logtext, "."); + utf_strcat(logtext, m->name); + utf_strcat(logtext, m->descriptor); - } else{ - sprintf(logtext+strlen(logtext), "(NOSYNC"); - } + if (m->flags & ACC_SYNCHRONIZED) + strcat(logtext, "(SYNC"); + else + strcat(logtext, "(NOSYNC"); + + if (m->flags & ACC_NATIVE) { + strcat(logtext, ",NATIVE"); + + code = m->code; - if (m->flags & ACC_NATIVE) { - sprintf(logtext+strlen(logtext), ",NATIVE"); -#if POINTERSIZE == 8 - sprintf(logtext+strlen(logtext), ")(0x%016lx) at position 0x%016lx\n", (ptrint) m->entrypoint, (ptrint) pos); +#if SIZEOF_VOID_P == 8 + sprintf(logtext + strlen(logtext), + ")(0x%016lx) at position 0x%016lx", + (ptrint) code->entrypoint, (ptrint) pos); #else - sprintf(logtext+strlen(logtext), ")(0x%08x) at position 0x%08x\n", (ptrint) m->entrypoint, (ptrint) pos); + sprintf(logtext + strlen(logtext), + ")(0x%08x) at position 0x%08x", + (ptrint) code->entrypoint, (ptrint) pos); #endif - } else { -#if POINTERSIZE == 8 - sprintf(logtext+strlen(logtext), ")(0x%016lx) at position 0x%016lx (", (ptrint) m->entrypoint, (ptrint) pos); + } else { + + /* XXX preliminary: This should get the actual codeinfo */ + /* in which the exception happened. */ + code = m->code; + +#if SIZEOF_VOID_P == 8 + sprintf(logtext + strlen(logtext), + ")(0x%016lx) at position 0x%016lx (", + (ptrint) code->entrypoint, (ptrint) pos); #else - sprintf(logtext+strlen(logtext), ")(0x%08x) at position 0x%08x (", (ptrint) m->entrypoint, (ptrint) pos); + sprintf(logtext + strlen(logtext), + ")(0x%08x) at position 0x%08x (", + (ptrint) code->entrypoint, (ptrint) pos); #endif - if (m->class->sourcefile == NULL) { - sprintf(logtext+strlen(logtext), ""); - } else { - utf_sprint(logtext+strlen(logtext), m->class->sourcefile); - } - sprintf(logtext+strlen(logtext), ":%d)\n", line); - } + if (m->class->sourcefile == NULL) + strcat(logtext, ""); + else + utf_strcat(logtext, m->class->sourcefile); - } else - sprintf(logtext+strlen(logtext), "call_java_method\n"); + sprintf(logtext + strlen(logtext), ":%d)", 0); + } - log_text(logtext); - } + } else + strcat(logtext, "call_java_method"); + + log_text(logtext); + + /* release memory */ + + dump_release(dumpsize); return xptr; } +#endif /* !defined(NDEBUG) */ + +/* builtin_trace_args ********************************************************** + + XXX + +*******************************************************************************/ + +#if !defined(NDEBUG) #ifdef TRACE_ARGS_NUM -void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, +void builtin_trace_args(s8 a0, s8 a1, +#if TRACE_ARGS_NUM >= 4 + s8 a2, s8 a3, +#endif /* TRACE_ARGS_NUM >= 4 */ #if TRACE_ARGS_NUM >= 6 s8 a4, s8 a5, -#endif +#endif /* TRACE_ARGS_NUM >= 6 */ #if TRACE_ARGS_NUM == 8 s8 a6, s8 a7, -#endif +#endif /* TRACE_ARGS_NUM == 8 */ methodinfo *m) { - s4 i; - char logtext[MAXLOGTEXT]; - for (i = 0; i < methodindent; i++) - logtext[i] = '\t'; - if (methodindent == 0) - sprintf(logtext + methodindent, "1st_call: "); - else - sprintf(logtext + methodindent, "called: "); - - utf_sprint_classname(logtext + strlen(logtext), m->class->name); - sprintf(logtext + strlen(logtext), "."); - utf_sprint(logtext + strlen(logtext), m->name); - utf_sprint(logtext + strlen(logtext), m->descriptor); - - if (m->flags & ACC_PUBLIC) sprintf(logtext + strlen(logtext), " PUBLIC"); - if (m->flags & ACC_PRIVATE) sprintf(logtext + strlen(logtext), " PRIVATE"); - if (m->flags & ACC_PROTECTED) sprintf(logtext + strlen(logtext), " PROTECTED"); - if (m->flags & ACC_STATIC) sprintf(logtext + strlen(logtext), " STATIC"); - if (m->flags & ACC_FINAL) sprintf(logtext + strlen(logtext), " FINAL"); - if (m->flags & ACC_SYNCHRONIZED) sprintf(logtext + strlen(logtext), " SYNCHRONIZED"); - if (m->flags & ACC_VOLATILE) sprintf(logtext + strlen(logtext), " VOLATILE"); - if (m->flags & ACC_TRANSIENT) sprintf(logtext + strlen(logtext), " TRANSIENT"); - if (m->flags & ACC_NATIVE) sprintf(logtext + strlen(logtext), " NATIVE"); - if (m->flags & ACC_INTERFACE) sprintf(logtext + strlen(logtext), " INTERFACE"); - if (m->flags & ACC_ABSTRACT) sprintf(logtext + strlen(logtext), " ABSTRACT"); - + methoddesc *md; + char *logtext; + s4 logtextlen; + s4 dumpsize; + s4 i; + s4 pos; + + md = m->parseddesc; + + /* calculate message length */ + + logtextlen = + strlen("4294967295 ") + + strlen("-2147483647-") + /* INT_MAX should be sufficient */ + methodindent + + strlen("called: ") + + utf_strlen(m->class->name) + + strlen(".") + + utf_strlen(m->name) + + utf_strlen(m->descriptor) + + strlen(" SYNCHRONIZED") + strlen("(") + strlen(")"); + + /* add maximal argument length */ - sprintf(logtext + strlen(logtext), "("); + logtextlen += strlen("0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, ...(255)"); - switch (m->paramcount) { + /* allocate memory */ + + dumpsize = dump_size(); + + logtext = DMNEW(char, logtextlen); + + callcount++; + + sprintf(logtext, "%10d ", callcount); + sprintf(logtext + strlen(logtext), "-%d-", methodindent); + + pos = strlen(logtext); + + for (i = 0; i < methodindent; i++) + logtext[pos++] = '\t'; + + strcpy(logtext + pos, "called: "); + + utf_strcat_classname(logtext, m->class->name); + strcat(logtext, "."); + utf_strcat(logtext, m->name); + utf_strcat(logtext, m->descriptor); + + if (m->flags & ACC_PUBLIC) strcat(logtext, " PUBLIC"); + if (m->flags & ACC_PRIVATE) strcat(logtext, " PRIVATE"); + if (m->flags & ACC_PROTECTED) strcat(logtext, " PROTECTED"); + if (m->flags & ACC_STATIC) strcat(logtext, " STATIC"); + if (m->flags & ACC_FINAL) strcat(logtext, " FINAL"); + if (m->flags & ACC_SYNCHRONIZED) strcat(logtext, " SYNCHRONIZED"); + if (m->flags & ACC_VOLATILE) strcat(logtext, " VOLATILE"); + if (m->flags & ACC_TRANSIENT) strcat(logtext, " TRANSIENT"); + if (m->flags & ACC_NATIVE) strcat(logtext, " NATIVE"); + if (m->flags & ACC_INTERFACE) strcat(logtext, " INTERFACE"); + if (m->flags & ACC_ABSTRACT) strcat(logtext, " ABSTRACT"); + + strcat(logtext, "("); + + /* xxxprintf ?Bug? an PowerPc Linux (rlwinm.inso) */ + /* Only Arguments in integer Registers are passed correctly here */ + /* long longs spilled on Stack have an wrong offset of +4 */ + /* So preliminary Bugfix: Only pass 3 params at once to sprintf */ + /* for SIZEOG_VOID_P == 4 && TRACE_ARGS_NUM == 8 */ + switch (md->paramcount) { case 0: break; -#if defined(__I386__) || defined(__POWERPC__) +#if SIZEOF_VOID_P == 4 case 1: - sprintf(logtext+strlen(logtext), "%llx", a0); + sprintf(logtext + strlen(logtext), + "0x%llx", + a0); break; case 2: - sprintf(logtext+strlen(logtext), "%llx, %llx", a0, a1); + sprintf(logtext + strlen(logtext), + "0x%llx, 0x%llx", + a0, a1); break; +#if TRACE_ARGS_NUM >= 4 case 3: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx", a0, a1, a2); + sprintf(logtext + strlen(logtext), + "0x%llx, 0x%llx, 0x%llx", + a0, a1, a2); break; case 4: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx", - a0, a1, a2, a3); + sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx" + , a0, a1, a2); + sprintf(logtext + strlen(logtext), ", 0x%llx", a3); + break; +#endif /* TRACE_ARGS_NUM >= 4 */ #if TRACE_ARGS_NUM >= 6 case 5: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx", - a0, a1, a2, a3, a4); + sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx" + , a0, a1, a2); + sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx", a3, a4); break; + case 6: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx", - a0, a1, a2, a3, a4, a5); + sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx" + , a0, a1, a2); + sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx, 0x%llx" + , a3, a4, a5); break; #endif /* TRACE_ARGS_NUM >= 6 */ #if TRACE_ARGS_NUM == 8 case 7: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx", - a0, a1, a2, a3, a4, a5, a6); + sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx" + , a0, a1, a2); + sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx, 0x%llx" + , a3, a4, a5); + sprintf(logtext + strlen(logtext), ", 0x%llx", a6); break; case 8: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx", - a0, a1, a2, a3, a4, a5, a6, a7); + sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx" + , a0, a1, a2); + sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx, 0x%llx" + , a3, a4, a5); + sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx", a6, a7); break; +#endif /* TRACE_ARGS_NUM == 8 */ default: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, %llx, %llx, ...(%d)", - a0, a1, a2, a3, a4, a5, a6, a7, m->paramcount - 8); - break; -#else /* TRACE_ARGS_NUM == 8 */ - default: - sprintf(logtext+strlen(logtext), "%llx, %llx, %llx, %llx, %llx, %llx, ...(%d)", - a0, a1, a2, a3, a4, a5, m->paramcount - 6); +#if TRACE_ARGS_NUM == 2 + sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, ...(%d)", a0, a1, md->paramcount - 2); + +#elif TRACE_ARGS_NUM == 4 + sprintf(logtext + strlen(logtext), + "0x%llx, 0x%llx, 0x%llx, 0x%llx, ...(%d)", + a0, a1, a2, a3, md->paramcount - 4); + +#elif TRACE_ARGS_NUM == 6 + sprintf(logtext + strlen(logtext), + "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, ...(%d)", + a0, a1, a2, a3, a4, a5, md->paramcount - 6); + +#elif TRACE_ARGS_NUM == 8 + sprintf(logtext + strlen(logtext),"0x%llx, 0x%llx, 0x%llx," + , a0, a1, a2); + sprintf(logtext + strlen(logtext)," 0x%llx, 0x%llx, 0x%llx," + , a3, a4, a5); + sprintf(logtext + strlen(logtext)," 0x%llx, 0x%llx, ...(%d)" + , a6, a7, md->paramcount - 8); +#endif break; -#endif /* TRACE_ARGS_NUM == 8 */ -#else /* defined(__I386__) || defined(__POWERPC__) */ + +#else /* SIZEOF_VOID_P == 4 */ + case 1: - sprintf(logtext+strlen(logtext), "%lx", a0); + sprintf(logtext + strlen(logtext), + "0x%lx", + a0); break; case 2: - sprintf(logtext+strlen(logtext), "%lx, %lx", a0, a1); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx", + a0, a1); break; case 3: - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx", a0, a1, a2); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx", a0, a1, a2); break; case 4: - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx", - a0, a1, a2, a3); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx", + a0, a1, a2, a3); break; #if TRACE_ARGS_NUM >= 6 case 5: - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx", - a0, a1, a2, a3, a4); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx", + a0, a1, a2, a3, a4); break; case 6: - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx", - a0, a1, a2, a3, a4, a5); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx", + a0, a1, a2, a3, a4, a5); break; #endif /* TRACE_ARGS_NUM >= 6 */ #if TRACE_ARGS_NUM == 8 case 7: - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx", - a0, a1, a2, a3, a4, a5, a6); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx", + a0, a1, a2, a3, a4, a5, a6); break; case 8: - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx", - a0, a1, a2, a3, a4, a5, a6, a7); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx", + a0, a1, a2, a3, a4, a5, a6, a7); break; #endif /* TRACE_ARGS_NUM == 8 */ default: #if TRACE_ARGS_NUM == 4 - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, ...(%d)", - a0, a1, a2, a3, m->paramcount - 4); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)", + a0, a1, a2, a3, md->paramcount - 4); #elif TRACE_ARGS_NUM == 6 - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, ...(%d)", - a0, a1, a2, a3, a4, a5, m->paramcount - 6); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)", + a0, a1, a2, a3, a4, a5, md->paramcount - 6); #elif TRACE_ARGS_NUM == 8 - sprintf(logtext+strlen(logtext), "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, ...(%d)", - a0, a1, a2, a3, a4, a5, a6, a7, m->paramcount - 8); + sprintf(logtext + strlen(logtext), + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)", + a0, a1, a2, a3, a4, a5, a6, a7, md->paramcount - 8); #endif break; -#endif /* defined(__I386__) || defined(__POWERPC__) */ +#endif /* SIZEOF_VOID_P == 4 */ } - sprintf(logtext + strlen(logtext), ")"); + strcat(logtext, ")"); + log_text(logtext); + /* release memory */ + + dump_release(dumpsize); + methodindent++; } #endif +#endif /* !defined(NDEBUG) */ -void builtin_displaymethodstart(methodinfo *m) -{ - char logtext[MAXLOGTEXT]; - sprintf(logtext, " "); - sprintf(logtext + methodindent, "called: "); - utf_sprint(logtext + strlen(logtext), m->class->name); - sprintf(logtext + strlen(logtext), "."); - utf_sprint(logtext + strlen(logtext), m->name); - utf_sprint(logtext + strlen(logtext), m->descriptor); - - if (m->flags & ACC_PUBLIC) sprintf(logtext + strlen(logtext), " PUBLIC"); - if (m->flags & ACC_PRIVATE) sprintf(logtext + strlen(logtext), " PRIVATE"); - if (m->flags & ACC_PROTECTED) sprintf(logtext + strlen(logtext), " PROTECTED"); - if (m->flags & ACC_STATIC) sprintf(logtext + strlen(logtext), " STATIC"); - if (m->flags & ACC_FINAL) sprintf(logtext + strlen(logtext), " FINAL"); - if (m->flags & ACC_SYNCHRONIZED) sprintf(logtext + strlen(logtext), " SYNCHRONIZED"); - if (m->flags & ACC_VOLATILE) sprintf(logtext + strlen(logtext), " VOLATILE"); - if (m->flags & ACC_TRANSIENT) sprintf(logtext + strlen(logtext), " TRANSIENT"); - if (m->flags & ACC_NATIVE) sprintf(logtext + strlen(logtext), " NATIVE"); - if (m->flags & ACC_INTERFACE) sprintf(logtext + strlen(logtext), " INTERFACE"); - if (m->flags & ACC_ABSTRACT) sprintf(logtext + strlen(logtext), " ABSTRACT"); +/* builtin_displaymethodstop *************************************************** - log_text(logtext); - methodindent++; -} + XXX +*******************************************************************************/ +#if !defined(NDEBUG) void builtin_displaymethodstop(methodinfo *m, s8 l, double d, float f) { - int i; - char logtext[MAXLOGTEXT]; - for (i = 0; i < methodindent; i++) - logtext[i] = '\t'; + methoddesc *md; + char *logtext; + s4 logtextlen; + s4 dumpsize; + s4 i; + s4 pos; + java_objectheader *o; + java_lang_String *s; + classinfo *c; + s4 len; + utf *u; + imm_union imu; + + md = m->parseddesc; + + /* calculate message length */ + + logtextlen = + strlen("4294967295 ") + + strlen("-2147483647-") + /* INT_MAX should be sufficient */ + methodindent + + strlen("finished: ") + + utf_strlen(m->class->name) + + strlen(".") + + utf_strlen(m->name) + + utf_strlen(m->descriptor) + + strlen(" SYNCHRONIZED") + strlen("(") + strlen(")"); + + /* add maximal argument length */ + + logtextlen += strlen("->0.4872328470301428 (0x0123456789abcdef)"); + + /* allocate memory */ + + dumpsize = dump_size(); + + logtext = DMNEW(char, logtextlen); + + /* outdent the log message */ + if (methodindent) methodindent--; else log_text("WARNING: unmatched methodindent--"); - sprintf(logtext + methodindent, "finished: "); - utf_sprint_classname(logtext + strlen(logtext), m->class->name); - sprintf(logtext + strlen(logtext), "."); - utf_sprint(logtext + strlen(logtext), m->name); - utf_sprint(logtext + strlen(logtext), m->descriptor); + /* generate the message */ + + sprintf(logtext, " "); + sprintf(logtext + strlen(logtext), "-%d-", methodindent); - switch (m->returntype) { + pos = strlen(logtext); + + for (i = 0; i < methodindent; i++) + logtext[pos++] = '\t'; + + strcpy(logtext + pos, "finished: "); + utf_strcat_classname(logtext, m->class->name); + strcat(logtext, "."); + utf_strcat(logtext, m->name); + utf_strcat(logtext, m->descriptor); + + switch (md->returntype.type) { case TYPE_INT: - sprintf(logtext + strlen(logtext), "->%d", (s4) l); + sprintf(logtext + strlen(logtext), "->%d (0x%08x)", (s4) l, (s4) l); break; - case TYPE_LONG: -#if defined(__I386__) || defined(__POWERPC__) - sprintf(logtext + strlen(logtext), "->%lld", (s8) l); + case TYPE_LNG: +#if SIZEOF_VOID_P == 4 + sprintf(logtext + strlen(logtext), "->%lld (0x%016llx)", (s8) l, l); #else - sprintf(logtext + strlen(logtext), "->%ld", (s8) l); + sprintf(logtext + strlen(logtext), "->%ld (0x%016lx)", (s8) l, l); #endif break; - case TYPE_ADDRESS: -#if defined(__I386__) || defined(__POWERPC__) - sprintf(logtext + strlen(logtext), "->%p", (u1*) ((s4) l)); -#else - sprintf(logtext + strlen(logtext), "->%p", (u1*) l); -#endif + case TYPE_ADR: + sprintf(logtext + strlen(logtext), "->%p", (void *) (ptrint) l); + + /* check return argument for java.lang.Class or java.lang.String */ + + o = (java_objectheader *) (ptrint) l; + + if (o != NULL) { + if (o->vftbl->class == class_java_lang_String) { + /* get java.lang.String object and the length of the + string */ + + s= (java_lang_String *) (ptrint) l; + + len = strlen(", String = \"") + javastring_strlen(s) + + strlen("\""); + + /* realloc memory for string length */ + + DMREALLOC(logtext, char, logtextlen, logtextlen + len); + + /* convert to utf8 string and strcat it to the logtext */ + + u = javastring_toutf(s, false); + + strcat(logtext, ", String = \""); + utf_strcat(logtext, u); + strcat(logtext, "\""); + + } else { + if (o->vftbl->class == class_java_lang_Class) { + /* if the object returned is a java.lang.Class + cast it to classinfo structure and get the name + of the class */ + + c = (classinfo *) (ptrint) l; + + u = c->name; + + } else { + /* if the object returned is not a java.lang.String or + a java.lang.Class just print the name of the class */ + + u = o->vftbl->class->name; + } + + len = strlen(", Class = \"") + utf_strlen(u) + strlen("\""); + + /* realloc memory for string length */ + + DMREALLOC(logtext, char, logtextlen, logtextlen + len); + + /* strcat to the logtext */ + + strcat(logtext, ", Class = \""); + utf_strcat(logtext, u); + strcat(logtext, "\""); + } + } break; - case TYPE_FLOAT: - sprintf(logtext + strlen(logtext), "->%g", f); + case TYPE_FLT: + imu.f = f; + sprintf(logtext + strlen(logtext), "->%.8f (0x%08x)", f, imu.i); break; - case TYPE_DOUBLE: - sprintf(logtext + strlen(logtext), "->%g", d); + case TYPE_DBL: + imu.d = d; +#if SIZEOF_VOID_P == 4 + sprintf(logtext + strlen(logtext), "->%.16g (0x%016llx)", d, imu.l); +#else + sprintf(logtext + strlen(logtext), "->%.16g (0x%016lx)", d, imu.l); +#endif break; } + log_text(logtext); + + /* release memory */ + + dump_release(dumpsize); } +#endif /* !defined(NDEBUG) */ /**************************************************************************** @@ -1431,20 +1779,16 @@ void builtin_monitorenter(java_objectheader *o) #if defined(USE_THREADS) /* * Locks the class object - needed for static synchronized methods. - * The use_class_as_object call is needed in order to circumvent a - * possible deadlock with builtin_monitorenter called by another - * thread calling use_class_as_object. */ void builtin_staticmonitorenter(classinfo *c) { - use_class_as_object(c); - builtin_monitorenter(&c->header); + builtin_monitorenter(&c->object.header); } #endif #if defined(USE_THREADS) -void *builtin_monitorexit(java_objectheader *o) +void builtin_monitorexit(java_objectheader *o) { #if !defined(NATIVE_THREADS) int hashValue; @@ -1463,10 +1807,8 @@ void *builtin_monitorexit(java_objectheader *o) internal_unlock_mutex_for_object(o); --blockInts; - return o; #else monitorExit((threadobject *) THREADOBJECT, o); - return o; #endif } #endif @@ -1485,143 +1827,248 @@ void *builtin_monitorexit(java_objectheader *o) ******************************************************************************/ -s4 builtin_idiv(s4 a, s4 b) { return a / b; } -s4 builtin_irem(s4 a, s4 b) { return a % b; } +#if !SUPPORT_DIVISION +s4 builtin_idiv(s4 a, s4 b) +{ + s4 c; + + c = a / b; + return c; +} -/************** Functions for long arithmetics ******************************* +s4 builtin_irem(s4 a, s4 b) +{ + s4 c; - On systems where 64 bit Integers are not supported by the CPU, these - functions are needed. + c = a % b; -******************************************************************************/ + return c; +} +#endif /* !SUPPORT_DIVISION */ + + +/* functions for long arithmetics ********************************************** + On systems where 64 bit Integers are not supported by the CPU, + these functions are needed. +******************************************************************************/ + +#if !(SUPPORT_LONG && SUPPORT_LONG_ADD) s8 builtin_ladd(s8 a, s8 b) -{ +{ + s8 c; + #if U8_AVAILABLE - return a + b; + c = a + b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } -s8 builtin_lsub(s8 a, s8 b) -{ +s8 builtin_lsub(s8 a, s8 b) +{ + s8 c; + #if U8_AVAILABLE - return a - b; + c = a - b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } -s8 builtin_lmul(s8 a, s8 b) -{ +s8 builtin_lneg(s8 a) +{ + s8 c; + #if U8_AVAILABLE - return a * b; + c = -a; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } +#endif /* !(SUPPORT_LONG && SUPPORT_LONG_ADD) */ + + +#if !(SUPPORT_LONG && SUPPORT_LONG_MUL) +s8 builtin_lmul(s8 a, s8 b) +{ + s8 c; -s8 builtin_ldiv(s8 a, s8 b) -{ #if U8_AVAILABLE - return a / b; + c = a * b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } +#endif /* !(SUPPORT_LONG && SUPPORT_LONG_MUL) */ + + +#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) +s8 builtin_ldiv(s8 a, s8 b) +{ + s8 c; -s8 builtin_lrem(s8 a, s8 b) -{ #if U8_AVAILABLE - return a % b; + c = a / b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } -s8 builtin_lshl(s8 a, s4 b) -{ +s8 builtin_lrem(s8 a, s8 b) +{ + s8 c; + #if U8_AVAILABLE - return a << (b & 63); + c = a % b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } +#endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */ + + +#if !(SUPPORT_LONG && SUPPORT_LONG_SHIFT) +s8 builtin_lshl(s8 a, s4 b) +{ + s8 c; -s8 builtin_lshr(s8 a, s4 b) -{ #if U8_AVAILABLE - return a >> (b & 63); + c = a << (b & 63); #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } -s8 builtin_lushr(s8 a, s4 b) -{ +s8 builtin_lshr(s8 a, s4 b) +{ + s8 c; + #if U8_AVAILABLE - return ((u8) a) >> (b & 63); + c = a >> (b & 63); #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } -s8 builtin_land(s8 a, s8 b) -{ +s8 builtin_lushr(s8 a, s4 b) +{ + s8 c; + #if U8_AVAILABLE - return a & b; + c = ((u8) a) >> (b & 63); #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } +#endif /* !(SUPPORT_LONG && SUPPORT_LONG_SHIFT) */ + + +#if !(SUPPORT_LONG && SUPPORT_LONG_LOGICAL) +s8 builtin_land(s8 a, s8 b) +{ + s8 c; -s8 builtin_lor(s8 a, s8 b) -{ #if U8_AVAILABLE - return a | b; + c = a & b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } -s8 builtin_lxor(s8 a, s8 b) -{ +s8 builtin_lor(s8 a, s8 b) +{ + s8 c; + #if U8_AVAILABLE - return a ^ b; + c = a | b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } -s8 builtin_lneg(s8 a) -{ +s8 builtin_lxor(s8 a, s8 b) +{ + s8 c; + #if U8_AVAILABLE - return -a; + c = a ^ b; #else - return builtin_i2l(0); + c = builtin_i2l(0); #endif + + return c; } +#endif /* !(SUPPORT_LONG && SUPPORT_LONG_LOGICAL) */ -s4 builtin_lcmp(s8 a, s8 b) + +#if !(SUPPORT_LONG && SUPPORT_LONG_CMP) +s4 builtin_lcmp(s8 a, s8 b) { #if U8_AVAILABLE - if (a < b) return -1; - if (a > b) return 1; + if (a < b) + return -1; + + if (a > b) + return 1; + return 0; #else return 0; #endif } +#endif /* !(SUPPORT_LONG && SUPPORT_LONG_CMP) */ + + +/* functions for unsupported floating instructions ****************************/ + +/* used to convert FLT_xxx defines into float values */ + +static inline float intBitsToFloat(s4 i) +{ + imm_union imb; + + imb.i = i; + return imb.f; +} +/* used to convert DBL_xxx defines into double values */ +static inline float longBitsToDouble(s8 l) +{ + imm_union imb; + imb.l = l; + return imb.d; +} -/*********** Functions for floating point operations *************************/ +#if !SUPPORT_FLOAT float builtin_fadd(float a, float b) { if (isnanf(a)) return intBitsToFloat(FLT_NAN); @@ -1674,25 +2121,64 @@ float builtin_fmul(float a, float b) } +/* builtin_ddiv **************************************************************** + + Implementation as described in VM Spec. + +*******************************************************************************/ + float builtin_fdiv(float a, float b) { - if (finitef(a) && finitef(b)) { - if (b != 0) + if (finitef(a)) { + if (finitef(b)) { + /* If neither value1' nor value2' is NaN, the sign of the result */ + /* is positive if both values have the same sign, negative if the */ + /* values have different signs. */ + return a / b; - else { - if (a > 0) + + } else { + if (isnanf(b)) { + /* If either value1' or value2' is NaN, the result is NaN. */ + + return intBitsToFloat(FLT_NAN); + + } else { + /* Division of a finite value by an infinity results in a */ + /* signed zero, with the sign-producing rule just given. */ + + /* is sign equal? */ + + if (copysignf(1.0, a) == copysignf(1.0, b)) + return 0.0; + else + return -0.0; + } + } + + } else { + if (isnanf(a)) { + /* If either value1' or value2' is NaN, the result is NaN. */ + + return intBitsToFloat(FLT_NAN); + + } else if (finitef(b)) { + /* Division of an infinity by a finite value results in a signed */ + /* infinity, with the sign-producing rule just given. */ + + /* is sign equal? */ + + if (copysignf(1.0, a) == copysignf(1.0, b)) return intBitsToFloat(FLT_POSINF); - else if (a < 0) + else return intBitsToFloat(FLT_NEGINF); - } - } - return intBitsToFloat(FLT_NAN); -} + } else { + /* Division of an infinity by an infinity results in NaN. */ -float builtin_frem(float a, float b) -{ - return fmodf(a, b); + return intBitsToFloat(FLT_NAN); + } + } } @@ -1704,8 +2190,10 @@ float builtin_fneg(float a) else return copysignf(a, -copysignf(1.0, a)); } } +#endif /* !SUPPORT_FLOAT */ +#if !SUPPORT_FLOAT || defined(ENABLE_INTRP) s4 builtin_fcmpl(float a, float b) { if (isnanf(a)) return -1; @@ -1732,11 +2220,18 @@ s4 builtin_fcmpg(float a, float b) if (a == b) return 0; return -1; } +#endif /* !SUPPORT_FLOAT || defined(ENABLE_INTRP) */ +float builtin_frem(float a, float b) +{ + return fmodf(a, b); +} + -/************************* Functions for doubles ****************************/ +/* functions for unsupported double instructions ******************************/ +#if !SUPPORT_DOUBLE double builtin_dadd(double a, double b) { if (isnan(a)) return longBitsToDouble(DBL_NAN); @@ -1784,62 +2279,100 @@ double builtin_dmul(double a, double b) } +/* builtin_ddiv **************************************************************** + + Implementation as described in VM Spec. + +*******************************************************************************/ + double builtin_ddiv(double a, double b) { if (finite(a)) { if (finite(b)) { + /* If neither value1' nor value2' is NaN, the sign of the result */ + /* is positive if both values have the same sign, negative if the */ + /* values have different signs. */ + return a / b; } else { - if (isnan(b)) + if (isnan(b)) { + /* If either value1' or value2' is NaN, the result is NaN. */ + return longBitsToDouble(DBL_NAN); - else - return copysign(0.0, b); + + } else { + /* Division of a finite value by an infinity results in a */ + /* signed zero, with the sign-producing rule just given. */ + + /* is sign equal? */ + + if (copysign(1.0, a) == copysign(1.0, b)) + return 0.0; + else + return -0.0; + } } } else { - if (finite(b)) { - if (a > 0) + if (isnan(a)) { + /* If either value1' or value2' is NaN, the result is NaN. */ + + return longBitsToDouble(DBL_NAN); + + } else if (finite(b)) { + /* Division of an infinity by a finite value results in a signed */ + /* infinity, with the sign-producing rule just given. */ + + /* is sign equal? */ + + if (copysign(1.0, a) == copysign(1.0, b)) return longBitsToDouble(DBL_POSINF); - else if (a < 0) + else return longBitsToDouble(DBL_NEGINF); - } else + } else { + /* Division of an infinity by an infinity results in NaN. */ + return longBitsToDouble(DBL_NAN); + } } - -/* if (finite(a) && finite(b)) { */ -/* if (b != 0) */ -/* return a / b; */ -/* else { */ -/* if (a > 0) */ -/* return longBitsToDouble(DBL_POSINF); */ -/* else if (a < 0) */ -/* return longBitsToDouble(DBL_NEGINF); */ -/* } */ -/* } */ - - /* keep compiler happy */ - return 0; } -double builtin_drem(double a, double b) -{ - return fmod(a, b); -} +/* builtin_dneg **************************************************************** + Implemented as described in VM Spec. + +*******************************************************************************/ double builtin_dneg(double a) { - if (isnan(a)) return a; - else { - if (finite(a)) return -a; - else return copysign(a, -copysign(1.0, a)); + if (isnan(a)) { + /* If the operand is NaN, the result is NaN (recall that NaN has no */ + /* sign). */ + + return a; + + } else { + if (finite(a)) { + /* If the operand is a zero, the result is the zero of opposite */ + /* sign. */ + + return -a; + + } else { + /* If the operand is an infinity, the result is the infinity of */ + /* opposite sign. */ + + return copysign(a, -copysign(1.0, a)); + } } } +#endif /* !SUPPORT_DOUBLE */ +#if !SUPPORT_DOUBLE || defined(ENABLE_INTRP) s4 builtin_dcmpl(double a, double b) { if (isnan(a)) return -1; @@ -1866,10 +2399,18 @@ s4 builtin_dcmpg(double a, double b) if (a == b) return 0; return -1; } +#endif /* !SUPPORT_DOUBLE || defined(ENABLE_INTRP) */ -/*********************** Conversion operations ****************************/ +double builtin_drem(double a, double b) +{ + return fmod(a, b); +} + +/* conversion operations ******************************************************/ + +#if 0 s8 builtin_i2l(s4 i) { #if U8_AVAILABLE @@ -1882,31 +2423,36 @@ s8 builtin_i2l(s4 i) #endif } +s4 builtin_l2i(s8 l) +{ +#if U8_AVAILABLE + return (s4) l; +#else + return l.low; +#endif +} +#endif + +#if !(SUPPORT_FLOAT && SUPPORT_I2F) float builtin_i2f(s4 a) { float f = (float) a; return f; } +#endif /* !(SUPPORT_FLOAT && SUPPORT_I2F) */ +#if !(SUPPORT_DOUBLE && SUPPORT_I2D) double builtin_i2d(s4 a) { double d = (double) a; return d; } +#endif /* !(SUPPORT_DOUBLE && SUPPORT_I2D) */ -s4 builtin_l2i(s8 l) -{ -#if U8_AVAILABLE - return (s4) l; -#else - return l.low; -#endif -} - - +#if !(SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_L2F) float builtin_l2f(s8 a) { #if U8_AVAILABLE @@ -1916,8 +2462,10 @@ float builtin_l2f(s8 a) return 0.0; #endif } +#endif /* !(SUPPORT_LONG && SUPPORT_FLOAT && SUPPORT_L2F) */ +#if !(SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_L2D) double builtin_l2d(s8 a) { #if U8_AVAILABLE @@ -1927,12 +2475,17 @@ double builtin_l2d(s8 a) return 0.0; #endif } +#endif /* !(SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_L2D) */ +#if !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) s4 builtin_f2i(float a) { + s4 i; - return builtin_d2i((double) a); + i = builtin_d2i((double) a); + + return i; /* float f; @@ -1950,12 +2503,17 @@ s4 builtin_f2i(float a) return 2147483647; return (-2147483648); */ } +#endif /* !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) */ +#if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) s8 builtin_f2l(float a) { + s8 l; + + l = builtin_d2l((double) a); - return builtin_d2l((double) a); + return l; /* float f; @@ -1973,20 +2531,10 @@ s8 builtin_f2l(float a) return 9223372036854775807L; return (-9223372036854775808L); */ } +#endif /* !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) */ -double builtin_f2d(float a) -{ - if (finitef(a)) return (double) a; - else { - if (isnanf(a)) - return longBitsToDouble(DBL_NAN); - else - return copysign(longBitsToDouble(DBL_POSINF), (double) copysignf(1.0, a) ); - } -} - - +#if !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) s4 builtin_d2i(double a) { double d; @@ -2005,8 +2553,10 @@ s4 builtin_d2i(double a) return 2147483647; return (-2147483647-1); } +#endif /* !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) */ +#if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) s8 builtin_d2l(double a) { double d; @@ -2025,8 +2575,21 @@ s8 builtin_d2l(double a) return 9223372036854775807LL; return (-9223372036854775807LL-1); } +#endif /* !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) */ +#if !(SUPPORT_FLOAT && SUPPORT_DOUBLE) +double builtin_f2d(float a) +{ + if (finitef(a)) return (double) a; + else { + if (isnanf(a)) + return longBitsToDouble(DBL_NAN); + else + return copysign(longBitsToDouble(DBL_POSINF), (double) copysignf(1.0, a) ); + } +} + float builtin_d2f(double a) { if (finite(a)) @@ -2038,41 +2601,25 @@ float builtin_d2f(double a) return copysignf(intBitsToFloat(FLT_POSINF), (float) copysign(1.0, a)); } } +#endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */ -/* used to convert FLT_xxx defines into float values */ +/* builtin_clone_array ********************************************************* -inline float intBitsToFloat(s4 i) -{ - imm_union imb; - - imb.i = i; - return imb.f; -} - - -/* used to convert DBL_xxx defines into double values */ - -inline float longBitsToDouble(s8 l) -{ - imm_union imb; - - imb.l = l; - return imb.d; -} + Wrapper function for cloning arrays. +*******************************************************************************/ java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o) { - return (java_arrayheader *) - Java_java_lang_VMObject_clone(0, 0, (java_lang_Cloneable *) o); -} + java_arrayheader *ah; + java_lang_Cloneable *c; + c = (java_lang_Cloneable *) o; -s4 builtin_dummy() -{ - panic("Internal error: builtin_dummy called (native function is missing)"); - return 0; /* for the compiler */ + ah = (java_arrayheader *) Java_java_lang_VMObject_clone(0, 0, c); + + return ah; } @@ -2083,50 +2630,13 @@ s4 builtin_dummy() *******************************************************************************/ #if defined(USE_THREADS) && defined(NATIVE_THREADS) -java_objectheader **builtin_asm_get_exceptionptrptr() +java_objectheader **builtin_asm_get_exceptionptrptr(void) { return builtin_get_exceptionptrptr(); } #endif -methodinfo *builtin_asm_get_threadrootmethod() -{ - return *threadrootmethod; -} - - -inline void* builtin_asm_get_stackframeinfo() -{ -/*log_text("builtin_asm_get_stackframeinfo()");*/ -#if defined(USE_THREADS) && defined(NATIVE_THREADS) - return &THREADINFO->_stackframeinfo; -#else -#if defined(__GNUC__) -#warning FIXME FOR OLD THREAD IMPL (jowenn) -#endif - return &_thread_nativestackframeinfo; /* no threading, at least no native*/ -#endif -} - -stacktraceelement *builtin_stacktrace_copy(stacktraceelement **el,stacktraceelement *begin, stacktraceelement *end) { -/* stacktraceelement *el;*/ - size_t s; - s=(end-begin); - /*printf ("begin: %p, end: %p, diff: %ld, size :%ld\n",begin,end,s,s*sizeof(stacktraceelement));*/ - *el=heap_allocate(sizeof(stacktraceelement)*(s+1), true, 0); -#if 0 - *el=MNEW(stacktraceelement,s+1); /*GC*/ -#endif - memcpy(*el,begin,(end-begin)*sizeof(stacktraceelement)); - (*el)[s].method=0; -#if defined(__GNUC__) -#warning change this if line numbers bigger than u2 are allowed, the currently supported class file format does no allow that -#endif - (*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 */ - return *el; -} - /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where @@ -2138,4 +2648,5 @@ stacktraceelement *builtin_stacktrace_copy(stacktraceelement **el,stacktraceelem * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */