array out of memory fixlet, InvocationTargetException handling, less debug output...
[cacao.git] / tables.c
index bbe2f1fe5cc147b2aba959e631ae88a614d359c4..435fb8fba77c263e9fbbbe8bb84467a25900a818 100644 (file)
--- a/tables.c
+++ b/tables.c
@@ -35,7 +35,7 @@
        - the heap
        - additional support functions
 
-   $Id: tables.c 562 2003-11-03 00:34:34Z twisti $
+   $Id: tables.c 700 2003-12-07 15:54:28Z edwin $
 
 */
 
@@ -54,8 +54,6 @@
 #include "toolbox/memory.h"
 
 
-bool runverbose = false;
-
 /* statistics */
 int count_utf_len = 0;         /* size of utf hash                  */
 int count_utf_new = 0;         /* calls of utf_new                  */
@@ -177,6 +175,32 @@ void utf_display (utf *u)
        fflush (stdout);
 }
 
+/************************* function: log_utf *********************************
+
+       log utf symbol
+
+******************************************************************************/
+
+void log_utf(utf *u)
+{
+       char buf[MAXLOGTEXT];
+       utf_sprint(buf,u);
+       dolog(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(buf);
+}
+
 /************************ function: utf_sprint *******************************
        
     write utf symbol into c-string (debugging purposes)                                                 
@@ -350,6 +374,7 @@ utf *utf_new (char *text, u2 length)
        utf *u;            /* hashtable element */
        u2 i;
        
+/*     log_text("utf_new entered");*/
 #ifdef STATISTICS
        count_utf_new++;
 #endif
@@ -369,7 +394,15 @@ utf *utf_new (char *text, u2 length)
 #ifdef STATISTICS
                        count_utf_new_found++;
 #endif
-                       /* symbol found in hashtable */                                 
+/*                     log_text("symbol found in hash table");*/
+                       /* symbol found in hashtable */
+/*                                     utf_display(u);
+                                       {
+                                               utf blup;
+                                               blup.blength=length;
+                                               blup.text=text;
+                                               utf_display(&blup);
+                                       }*/
                        return u;
                }
        nomatch:
@@ -384,8 +417,9 @@ utf *utf_new (char *text, u2 length)
        u = NEW (utf);
        u->blength  = length;             /* length in bytes of utfstring */
        u->hashlink = utf_hash.ptr[slot]; /* link in external hashchain   */            
-       u->text     = mem_alloc(length);  /* allocate memory for utf-text */
+       u->text     = mem_alloc(length/*JOWENN*/+1);  /* allocate memory for utf-text */
        memcpy(u->text,text,length);      /* copy utf-text                */
+        u->text[length]='\0';/*JOWENN*/
        utf_hash.ptr[slot] = u;           /* insert symbol into table     */ 
 
        utf_hash.entries++;               /* update number of entries     */
@@ -426,7 +460,7 @@ utf *utf_new (char *text, u2 length)
                MFREE (utf_hash.ptr, void*, utf_hash.size);
                utf_hash = newhash;
        }
-       
+               /*utf_display(u);*/
        return u;
 }
 
@@ -443,6 +477,33 @@ utf *utf_new_char (char *text)
        return utf_new(text, strlen(text));
 }
 
+
+/********************* function: utf_new_char ********************************
+
+    creates a new utf symbol, the text for this symbol is passed
+    as a c-string ( = char* )
+    "." characters are going to be replaced by "/". since the above function is
+    used often, this is a separte function, instead of an if
+
+******************************************************************************/
+
+utf *utf_new_char_classname (char *text)
+{
+       if (strchr(text,'.')) {
+               char *txt=strdup(text);
+               char *end=txt+strlen(txt);
+               char *c;
+               utf *tmpRes;
+               for (c=txt;c<end;c++)
+                       if (*c=='.') *c='/';
+               tmpRes=utf_new(txt,strlen(txt));
+               free(txt);
+               return tmpRes;
+       }
+       else
+       return utf_new(text, strlen(text));
+}
+
 /************************** Funktion: utf_show ******************************
 
     writes the utf symbols in the utfhash to stdout and
@@ -550,6 +611,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");
        
@@ -568,7 +630,7 @@ u2 desc_to_type(utf *descriptor)
                        
        sprintf(logtext, "Invalid Type-Descriptor: ");
        utf_sprint(logtext+strlen(logtext), descriptor);
-       error();
+       error(logtext);
 
        return 0;
 }
@@ -685,30 +747,34 @@ classinfo *class_new(utf *u)
        count_class_infos += sizeof(classinfo);
 #endif
 
-       c = NEW(classinfo);
-       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->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 = 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);
@@ -752,6 +818,10 @@ classinfo *class_new(utf *u)
                class_hash = newhash;
        }
                        
+    /* Array classes need further initialization. */
+    if (u->text[0] == '[')
+        class_new_array(c);
+        
        return c;
 }
 
@@ -773,6 +843,9 @@ classinfo *class_get(utf *u)
        slot = key & (class_hash.size-1);
        c    = class_hash.ptr[slot];
 
+/*
+       log_text("class_get: looking for class:");
+       utf_display(u); */
        /* search external hash-chain */
        while (c) {
                if (c->name->blength == u->blength) {
@@ -780,7 +853,11 @@ classinfo *class_get(utf *u)
                        /* compare classnames */
                        for (i=0; i<u->blength; i++) 
                                if (u->text[i] != c->name->text[i]) goto nomatch;
-
+/*
+                       log_text("class_get: class found");
+                       utf_display(u);
+                       log_text("");
+                       utf_display(c->name); */
                        /* class found in hashtable */                          
                        return c;
                }
@@ -793,6 +870,77 @@ classinfo *class_get(utf *u)
        return NULL;
 }
 
+/***************** Function: class_array_of ***********************************
+
+    Returns an array class with the given component class.
+    The array class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_array_of(classinfo *component)
+{
+    int namelen;
+    char *namebuf;
+
+    /* Assemble the array class name */
+    namelen = component->name->blength;
+    
+    if (component->name->text[0] == '[') {
+        /* the component is itself an array */
+        namebuf = DMNEW(char,namelen+1);
+        namebuf[0] = '[';
+        memcpy(namebuf+1,component->name->text,namelen);
+        namelen++;
+    }
+    else {
+        /* the component is a non-array class */
+        namebuf = DMNEW(char,namelen+3);
+        namebuf[0] = '[';
+        namebuf[1] = 'L';
+        memcpy(namebuf+2,component->name->text,namelen);
+        namebuf[2+namelen] = ';';
+        namelen+=3;
+    }
+
+    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 ******************************