show_icmd bugfix
[cacao.git] / tables.c
index 4b39eb9fffefd986fbaa8f7fc65b444a226f1837..ebe1d3dedb2dbe73657b99d100af56d37fe5d852 100644 (file)
--- a/tables.c
+++ b/tables.c
@@ -35,7 +35,7 @@
        - the heap
        - additional support functions
 
-   $Id: tables.c 682 2003-12-01 15:33:30Z jowenn $
+   $Id: tables.c 775 2003-12-14 12:57:05Z edwin $
 
 */
 
@@ -47,6 +47,7 @@
 #include "types.h"
 #include "global.h"
 #include "tables.h"
+#include "loader.h"
 #include "asmpart.h"
 #include "threads/thread.h"
 #include "threads/locks.h"
@@ -153,26 +154,56 @@ void tables_close (stringdeleter del)
        MFREE (class_hash.ptr,  void*, class_hash.size);
 }
 
+
 /********************* function: utf_display *********************************
 
        write utf symbol to stdout (debugging purposes)
 
 ******************************************************************************/
 
-void utf_display (utf *u)
+void utf_display(utf *u)
 {
     char *endpos  = utf_end(u);  /* points behind utf string       */
     char *utf_ptr = u->text;     /* current position in utf text   */
-       if (u==NULL) return;
-    while (utf_ptr<endpos) {
 
+       if (u == NULL)
+               return;
+
+    while (utf_ptr < endpos) {
                /* read next unicode character */                
-               u2 c = utf_nextu2(&utf_ptr);                            
-               if (c>=32 && c<=127) printf ("%c",c);
-               else printf ("?");
+               u2 c = utf_nextu2(&utf_ptr);
+               if (c >= 32 && c <= 127) printf("%c", c);
+               else printf("?");
        }
 
-       fflush (stdout);
+       fflush(stdout);
+}
+
+
+/************************* function: log_utf *********************************
+
+       log utf symbol
+
+******************************************************************************/
+
+void log_utf(utf *u)
+{
+       char buf[MAXLOGTEXT];
+       utf_sprint(buf,u);
+       dolog("%s",buf);
+}
+
+/********************** function: log_plain_utf ******************************
+
+       log utf symbol (without printing "LOG: " and newline)
+
+******************************************************************************/
+
+void log_plain_utf(utf *u)
+{
+       char buf[MAXLOGTEXT];
+       utf_sprint(buf,u);
+       dolog_plain("%s",buf);
 }
 
 /************************ function: utf_sprint *******************************
@@ -585,6 +616,7 @@ void utf_show ()
 u2 desc_to_type(utf *descriptor)
 {
        char *utf_ptr = descriptor->text;  /* current position in utf text */
+       char logtext[MAXLOGTEXT];
 
        if (descriptor->blength < 1) panic("Type-Descriptor is empty string");
        
@@ -603,7 +635,7 @@ u2 desc_to_type(utf *descriptor)
                        
        sprintf(logtext, "Invalid Type-Descriptor: ");
        utf_sprint(logtext+strlen(logtext), descriptor);
-       error();
+       error("%s",logtext);
 
        return 0;
 }
@@ -680,6 +712,72 @@ u2 utf_nextu2(char **utf_ptr)
     return unicode_char;
 }
 
+/********************* function: is_valid_utf ********************************
+
+    return true if the given string is a valid UTF-8 string
+
+    utf_ptr...points to first character
+    end_pos...points after last character
+
+******************************************************************************/
+
+static unsigned long min_codepoint[6] = {0,1L<<7,1L<<11,1L<<16,1L<<21,1L<<26};
+
+bool
+is_valid_utf(char *utf_ptr,char *end_pos)
+{
+       int bytes;
+       int len,i;
+       char c;
+       unsigned long v;
+
+       if (end_pos < utf_ptr) return false;
+       bytes = end_pos - utf_ptr;
+       while (bytes--) {
+               c = *utf_ptr++;
+               /*dolog("%c %02x",c,c);*/
+               if (!c) return false;                     /* 0x00 is not allowed */
+               if ((c & 0x80) == 0) continue;            /* ASCII */
+
+               if      ((c & 0xe0) == 0xc0) len = 1;     /* 110x xxxx */
+               else if ((c & 0xf0) == 0xe0) len = 2;     /* 1110 xxxx */
+               else if ((c & 0xf8) == 0xf0) len = 3;     /* 1111 0xxx */
+               else if ((c & 0xfc) == 0xf8) len = 4;     /* 1111 10xx */
+               else if ((c & 0xfe) == 0xfc) len = 5;     /* 1111 110x */
+               else return false;                        /* invalid leading byte */
+
+               if (len > 2) return false;                /* Java limitation */
+
+               v = (unsigned long)c & (0x3f >> len);
+               
+               if ((bytes -= len) < 0) return false;     /* missing bytes */
+
+               for (i = len; i--; ) {
+                       c = *utf_ptr++;
+                       /*dolog("    %c %02x",c,c);*/
+                       if ((c & 0xc0) != 0x80)               /* 10xx xxxx */
+                               return false;
+                       v = (v<<6) | (c & 0x3f);
+               }
+
+               /*              dolog("v=%d",v);*/
+
+               if (v == 0) {
+                       if (len != 1) return false;           /* Java special */
+               }
+               else {
+                       if (v < min_codepoint[len]) return false; /* overlong UTF-8 */
+               }
+
+               /* surrogates in UTF-8 seem to be allowed in Java classfiles */
+               /* if (v >= 0xd800 && v <= 0xdfff) return false; */ /* surrogates */
+
+               /* even these seem to be allowed */
+               /* if (v == 0xfffe || v == 0xffff) return false; */ /* invalid codepoints */
+       }
+
+       return true;
+}
  
 /******************** Function: class_new **************************************
 
@@ -720,34 +818,34 @@ classinfo *class_new(utf *u)
        count_class_infos += sizeof(classinfo);
 #endif
 
-       c = GCNEW (classinfo,1); /*JOWENN: NEW*/
-       c -> vmClass = 0;
-       c -> flags = 0;
-       c -> name = u;
-       c -> cpcount = 0;
-       c -> cptags = NULL;
-       c -> cpinfos = NULL;
-       c -> super = NULL;
-       c -> sub = NULL;
-       c -> nextsub = NULL;
-       c -> interfacescount = 0;
-       c -> interfaces = NULL;
-       c -> fieldscount = 0;
-       c -> fields = NULL;
-       c -> methodscount = 0;
-       c -> methods = NULL;
-       c -> linked = false;
-       c -> loaded = false;
-       c -> index = 0;
-       c -> instancesize = 0;
-       c -> header.vftbl = NULL;
-       c -> innerclasscount = 0;
-       c -> innerclass = NULL;
-       c -> vftbl = NULL;
-       c -> initialized = false;
-       c -> classvftbl = false;
-    c -> classUsed = 0;
-    c -> impldBy = NULL;
+       c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
+       c->vmClass = 0;
+       c->flags = 0;
+       c->name = u;
+       c->cpcount = 0;
+       c->cptags = NULL;
+       c->cpinfos = NULL;
+       c->super = NULL;
+       c->sub = NULL;
+       c->nextsub = NULL;
+       c->interfacescount = 0;
+       c->interfaces = NULL;
+       c->fieldscount = 0;
+       c->fields = NULL;
+       c->methodscount = 0;
+       c->methods = NULL;
+       c->linked = false;
+       c->loaded = false;
+       c->index = 0;
+       c->instancesize = 0;
+       c->header.vftbl = NULL;
+       c->innerclasscount = 0;
+       c->innerclass = NULL;
+       c->vftbl = NULL;
+       c->initialized = false;
+       c->classvftbl = false;
+    c->classUsed = 0;
+    c->impldBy = NULL;
        
        /* prepare loading of the class */
        list_addlast(&unloadedclasses, c);
@@ -769,7 +867,7 @@ classinfo *class_new(utf *u)
                hashtable newhash;  /* the new hashtable */
 
                /* create new hashtable, double the size */
-               init_hashtable(&newhash, class_hash.size*2);
+               init_hashtable(&newhash, class_hash.size * 2);
                newhash.entries = class_hash.entries;
 
                /* transfer elements to new hashtable */
@@ -878,6 +976,43 @@ classinfo *class_array_of(classinfo *component)
     return class_new( utf_new(namebuf,namelen) );
 }
 
+/*************** Function: class_multiarray_of ********************************
+
+    Returns an array class with the given dimension and element class.
+    The array class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_multiarray_of(int dim,classinfo *element)
+{
+    int namelen;
+    char *namebuf;
+
+       if (dim<1)
+               panic("Invalid array dimension requested");
+
+    /* Assemble the array class name */
+    namelen = element->name->blength;
+    
+    if (element->name->text[0] == '[') {
+        /* the element is itself an array */
+        namebuf = DMNEW(char,namelen+dim);
+        memcpy(namebuf+dim,element->name->text,namelen);
+        namelen += dim;
+    }
+    else {
+        /* the element is a non-array class */
+        namebuf = DMNEW(char,namelen+2+dim);
+        namebuf[dim] = 'L';
+        memcpy(namebuf+dim+1,element->name->text,namelen);
+        namelen += (2+dim);
+        namebuf[namelen-1] = ';';
+    }
+       memset(namebuf,'[',dim);
+
+    return class_new( utf_new(namebuf,namelen) );
+}
+
 /************************** function: utf_strlen ******************************
 
     determine number of unicode characters in the utf string