Replaced asm_wrapper_patcher_BUILTIN_* with PATCHER_builtin_* macros in
[cacao.git] / src / vm / builtin.c
index cc6ca263fb4d1e4f0a881ced2b7e652b95dccf27..4d9f4bdf643ffbc5decd79f62d3c687e5ba79147 100644 (file)
@@ -36,7 +36,7 @@
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 2255 2005-04-11 09:40:23Z twisti $
+   $Id: builtin.c 2369 2005-04-25 14:06:16Z twisti $
 
 */
 
@@ -74,6 +74,7 @@
 #include "vm/stringlocal.h"
 #include "vm/tables.h"
 #include "vm/jit/asmpart.h"
+#include "vm/jit/patcher.h"
 
 
 #undef DEBUG /*define DEBUG 1*/
@@ -239,7 +240,6 @@ builtin_descriptor builtin_desc[] = {
        {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"},
-       {255,BUILTIN_anewarray       ,ICMD_BUILTIN2,TYPE_INT   ,TYPE_ADR   ,TYPE_VOID  ,TYPE_ADR   ,0,0,"anewarray"},
 #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"},
@@ -256,10 +256,14 @@ builtin_descriptor builtin_desc[] = {
        {255,BUILTIN_drem            ,ICMD_BUILTIN2,TYPE_DOUBLE,TYPE_DOUBLE,TYPE_VOID  ,TYPE_DOUBLE,0,0,"drem"},
 
 
+#if defined(__X86_64__) || defined(__I386__)
        /* assembler code patching functions */
 
-       { 255, asm_builtin_new       , ICMD_BUILTIN1, TYPE_ADR   , TYPE_VOID  , TYPE_VOID  , TYPE_ADR   , 0, 0, "new (calling asm_builtin_new)" },
-       { 255, asm_builtin_newarray  , ICMD_BUILTIN1, TYPE_ADR   , TYPE_VOID  , TYPE_VOID  , TYPE_ADR   , 0, 0, "newarray (calling asm_builtin_newarray)" },
+       { 255, PATCHER_builtin_new            , ICMD_BUILTIN1, TYPE_ADR   , TYPE_VOID  , TYPE_VOID  , TYPE_ADR   , 0, 0, "new (calling patcher_builtin_new)" },
+       { 255, PATCHER_builtin_newarray       , ICMD_BUILTIN1, TYPE_ADR   , TYPE_VOID  , TYPE_VOID  , TYPE_ADR   , 0, 0, "newarray (calling patcher_builtin_newarray)" },
+       { 255, PATCHER_builtin_checkarraycast , ICMD_BUILTIN2, TYPE_ADR   , TYPE_ADR   , TYPE_VOID  , TYPE_VOID  , 0, 0, "checkarraycast (calling patcher_builtin_checkarraycast)" },
+       { 255, PATCHER_builtin_arrayinstanceof, ICMD_BUILTIN2, TYPE_ADR   , TYPE_ADR   , TYPE_VOID  , TYPE_INT   , 0, 0, "arrayinstanceof (calling patcher_builtin_arrayinstanceof)" },
+#endif
 
 
        /* this record marks the end of the list */
@@ -431,21 +435,28 @@ s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
 }
 
 
-/*********** 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;
@@ -458,30 +469,29 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *t
 }
 
 
-/******************** function: builtin_checkarraycast ***********************
+/* builtin_checkarraycast ******************************************************
 
-       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)
 {
        arraydescriptor *desc;
-       
-       if (!o) return 1;
-       if ((desc = o->vftbl->arraydesc) == NULL) return 0;
 
+       if (!o)
+               return 1;
+
+       if ((desc = o->vftbl->arraydesc) == NULL)
+               return 0;
        return builtin_descriptorscompatible(desc, target->arraydesc);
 }
 
@@ -726,7 +736,7 @@ java_objectheader *builtin_new(classinfo *c)
 
    Creates an array with the given vftbl on the heap.
 
-   Return value:  pointer to the array or NULL if no memory is available
+   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.
@@ -776,17 +786,14 @@ java_arrayheader *builtin_newarray(s4 size, vftbl_t *arrayvftbl)
 }
 
 
-/********************** Function: builtin_anewarray *************************
+/* builtin_anewarray ***********************************************************
 
-       Creates an array of references to the given class type on the heap.
+   Creates an array of references to the given class type on the heap.
 
-       Return value: pointer to the array or NULL if no memory is available
-
-    XXX This function does not do The Right Thing, because it uses a
-    classinfo pointer at runtime. builtin_newarray should be used
-    instead.
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_objectarray *builtin_anewarray(s4 size, classinfo *component)
 {
@@ -800,176 +807,193 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *component)
                if (!link_class(component))
                        return NULL;
 
-       c = class_array_of(component,true);
+       c = class_array_of(component, true);
+
        if (!c)
                return NULL;
+
        return (java_objectarray *) builtin_newarray(size, c->vftbl);
 }
 
 
-/******************** Function: builtin_newarray_int ***********************
+/* builtin_newarray_int ********************************************************
 
-       Creates an array of 32 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
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_intarray *builtin_newarray_int(s4 size)
 {
-       return (java_intarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
+       return (java_intarray *)
+               builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
 }
 
 
-/******************** Function: builtin_newarray_long ***********************
+/* builtin_newarray_long *******************************************************
 
-       Creates an array of 64 bit Integers 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
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_longarray *builtin_newarray_long(s4 size)
 {
-       return (java_longarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
+       return (java_longarray *)
+               builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
 }
 
 
-/******************** function: builtin_newarray_float ***********************
+/* builtin_newarray_float ******************************************************
 
-       Creates an array of 32 bit IEEE floats 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
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_floatarray *builtin_newarray_float(s4 size)
 {
-       return (java_floatarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
+       return (java_floatarray *)
+               builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
 }
 
 
-/******************** function: builtin_newarray_double ***********************
+/* builtin_newarray_double *****************************************************
 
-       Creates an array of 64 bit IEEE floats on the heap.
+   Creates an array of 64 bit IEEE floats on the heap.
 
-       Return value:  pointer to the array or NULL if no memory is available
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_doublearray *builtin_newarray_double(s4 size)
 {
-       return (java_doublearray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
+       return (java_doublearray *)
+               builtin_newarray(size,
+                                                primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
 }
 
 
-/******************** function: builtin_newarray_byte ***********************
+/* builtin_newarray_byte *******************************************************
 
-       Creates an array of 8 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
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_bytearray *builtin_newarray_byte(s4 size)
 {
-       return (java_bytearray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
+       return (java_bytearray *)
+               builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
 }
 
 
-/******************** function: builtin_newarray_char ************************
+/* builtin_newarray_char *******************************************************
 
-       Creates an array of characters on the heap.
+   Creates an array of characters on the heap.
 
-       Return value:  pointer to the array or NULL if no memory is available
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_chararray *builtin_newarray_char(s4 size)
 {
-       return (java_chararray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
+       return (java_chararray *)
+               builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
 }
 
 
-/******************** function: builtin_newarray_short ***********************
+/* builtin_newarray_short ******************************************************
 
-       Creates an array of 16 bit Integers 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
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_shortarray *builtin_newarray_short(s4 size)
 {
-       return (java_shortarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
+       return (java_shortarray *)
+               builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
 }
 
 
-/******************** function: builtin_newarray_boolean ************************
+/* builtin_newarray_boolean ****************************************************
 
-       Creates an array of bytes on the heap. The array is designated as an array
-       of booleans (important for casts)
+   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
+   Return value: pointer to the array or NULL if no memory is
+   available
 
-*****************************************************************************/
+*******************************************************************************/
 
 java_booleanarray *builtin_newarray_boolean(s4 size)
 {
-       return (java_booleanarray*) builtin_newarray(size, primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
+       return (java_booleanarray *)
+               builtin_newarray(size,
+                                                primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
 }
 
 
-/**************** function: builtin_nmultianewarray ***************************
+/* builtin_multianewarray ******************************************************
 
-       Creates a multi-dimensional array on the heap. The dimensions are passed in
-       an array of longs.
+   Creates a multi-dimensional array on the heap. The dimensions are
+   passed in an array of longs.
 
-    Arguments:
-        n............number of dimensions to create
-        arrayvftbl...vftbl of the array class
-        dims.........array containing the size of each dimension to create
+   Arguments:
+       n............number of dimensions to create
+       arrayvftbl...vftbl of the array class
+       dims.........array containing the size of each dimension to create
 
-       Return value:  pointer to the array or NULL if no memory is available
+   Return value: pointer to the array or NULL if no memory is
+   available
 
 ******************************************************************************/
 
-java_arrayheader *builtin_nmultianewarray(int n, vftbl_t *arrayvftbl, long *dims)
-/*  java_arrayheader *builtin_nmultianewarray(int n, classinfo *arrayclass, long *dims) */
+java_arrayheader *builtin_multianewarray(int n, vftbl_t *arrayvftbl, long *dims)
 {
        s4 size, i;
        java_arrayheader *a;
        vftbl_t *componentvftbl;
 
-/*     utf_display(arrayclass->name); */
-
-/*     class_load(arrayclass); */
-/*     class_link(arrayclass); */
-       
        /* create this dimension */
+
        size = (s4) dims[0];
        a = builtin_newarray(size, arrayvftbl);
-/*     a = builtin_newarray(size, arrayclass->vftbl); */
 
        if (!a)
                return NULL;
 
        /* if this is the last dimension return */
+
        if (!--n)
                return a;
 
        /* get the vftbl of the components to create */
+
        componentvftbl = arrayvftbl->arraydesc->componentvftbl;
-/*     component = arrayclass->vftbl->arraydesc; */
 
        /* The verifier guarantees this. */
        /* if (!componentvftbl) */
        /*      panic ("multianewarray with too many dimensions"); */
 
        /* create the component arrays */
+
        for (i = 0; i < size; i++) {
                java_arrayheader *ea = 
-                       builtin_nmultianewarray(n, componentvftbl, dims + 1);
+                       builtin_multianewarray(n, componentvftbl, dims + 1);
 
                if (!ea)
                        return NULL;
@@ -997,6 +1021,8 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
                                                                                   s4 line,
                                                                                   s4 noindent)
 {
+       char logtext[MAXLOGTEXT];
+       
        if (!noindent) {
                if (methodindent)
                        methodindent--;
@@ -1005,51 +1031,52 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
        }
        if (opt_verbose || runverbose || verboseexception) {
                if (xptr) {
-                       printf("Exception ");
-                       utf_display_classname(xptr->vftbl->class->name);
+                       sprintf(logtext,"Exception ");
+                       utf_sprint_classname(logtext+strlen(logtext), xptr->vftbl->class->name);
 
                } else {
-                       printf("Some Throwable");
+                       sprintf(logtext,"Some Throwable");
                }
-               printf(" thrown in ");
+               sprintf(logtext+strlen(logtext), " thrown in ");
 
                if (m) {
-                       utf_display_classname(m->class->name);
-                       printf(".");
-                       utf_display(m->name);
+                       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) {
-                               printf("(SYNC");
+                               sprintf(logtext+strlen(logtext), "(SYNC");
 
                        } else{
-                               printf("(NOSYNC");
+                               sprintf(logtext+strlen(logtext), "(NOSYNC");
                        }
 
                        if (m->flags & ACC_NATIVE) {
-                               printf(",NATIVE");
+                               sprintf(logtext+strlen(logtext), ",NATIVE");
 #if POINTERSIZE == 8
-                               printf(")(0x%016lx) at position 0x%016lx\n", (ptrint) m->entrypoint, (ptrint) pos);
+                               sprintf(logtext+strlen(logtext), ")(0x%016lx) at position 0x%016lx\n", (ptrint) m->entrypoint, (ptrint) pos);
 #else
-                               printf(")(0x%08x) at position 0x%08x\n", (ptrint) m->entrypoint, (ptrint) pos);
+                               sprintf(logtext+strlen(logtext), ")(0x%08x) at position 0x%08x\n", (ptrint) m->entrypoint, (ptrint) pos);
 #endif
 
                        } else {
 #if POINTERSIZE == 8
-                               printf(")(0x%016lx) at position 0x%016lx (", (ptrint) m->entrypoint, (ptrint) pos);
+                               sprintf(logtext+strlen(logtext), ")(0x%016lx) at position 0x%016lx (", (ptrint) m->entrypoint, (ptrint) pos);
 #else
-                               printf(")(0x%08x) at position 0x%08x (", (ptrint) m->entrypoint, (ptrint) pos);
+                               sprintf(logtext+strlen(logtext), ")(0x%08x) at position 0x%08x (", (ptrint) m->entrypoint, (ptrint) pos);
 #endif
                                if (m->class->sourcefile == NULL) {
-                                       printf("<NO CLASSFILE INFORMATION>");
+                                       sprintf(logtext+strlen(logtext), "<NO CLASSFILE INFORMATION>");
 
                                } else {
-                                       utf_display(m->class->sourcefile);
+                                       utf_sprint(logtext+strlen(logtext), m->class->sourcefile);
                                }
-                               printf(":%d)\n", line);
+                               sprintf(logtext+strlen(logtext), ":%d)\n", line);
                        }
 
                } else
-                       printf("call_java_method\n");
-               fflush(stdout);
+                       sprintf(logtext+strlen(logtext), "call_java_method\n");
+
+               log_text(logtext);
        }
 
        return xptr;
@@ -1071,7 +1098,7 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3,
        for (i = 0; i < methodindent; i++)
                logtext[i] = '\t';
        if (methodindent == 0) 
-                       sprintf(logtext + methodindent, "1st_call: ");
+               sprintf(logtext + methodindent, "1st_call: ");
        else
                sprintf(logtext + methodindent, "called: ");
 
@@ -1422,7 +1449,7 @@ void builtin_staticmonitorenter(classinfo *c)
 
 
 #if defined(USE_THREADS)
-void *builtin_monitorexit(java_objectheader *o)
+void builtin_monitorexit(java_objectheader *o)
 {
 #if !defined(NATIVE_THREADS)
        int hashValue;
@@ -1441,10 +1468,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
@@ -2078,6 +2103,7 @@ inline void* builtin_asm_get_stackframeinfo()
 {
 /*log_text("builtin_asm_get_stackframeinfo()");*/
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       /*printf("stackframeinfo: %p,%p\n",&THREADINFO->_stackframeinfo,*(&THREADINFO->_stackframeinfo));*/
        return &THREADINFO->_stackframeinfo;
 #else
 #if defined(__GNUC__)