* renamed CACAO_TYPECHECK to ENABLE_VERIFIER
[cacao.git] / src / vm / utf8.c
index 9e5915fd4e5693c50957438618e597aee6e81c98..d704f02eba24404d55e4d1c49d0d6fa4849503fa 100644 (file)
             Andreas Krall
             Christian Thalinger
 
-   $Id: utf8.c 2322 2005-04-21 22:17:46Z twisti $
+   $Id: utf8.c 3807 2005-11-26 21:51:11Z edwin $
 
 */
 
 
 #include <string.h>
+#include <assert.h>
 
 #include "mm/memory.h"
 #include "vm/exceptions.h"
 #include "vm/options.h"
 #include "vm/statistics.h"
+#include "vm/stringlocal.h"
 #include "vm/tables.h"
 #include "vm/utf8.h"
 
+/* global variables ***********************************************************/
+
+#if defined(USE_THREADS)
+static java_objectheader *lock_utf_hashtable;
+#endif
 
 hashtable utf_hash;                     /* hashtable for utf8-symbols         */
 
@@ -64,10 +71,17 @@ utf *utf_java_io_Serializable;
 utf *utf_java_lang_Throwable;
 utf *utf_java_lang_VMThrowable;
 utf *utf_java_lang_Error;
-utf *utf_java_lang_Exception;
 utf *utf_java_lang_NoClassDefFoundError;
+utf *utf_java_lang_LinkageError;
+utf *utf_java_lang_NoSuchMethodError;
 utf *utf_java_lang_OutOfMemoryError;
+
+utf *utf_java_lang_Exception;
 utf *utf_java_lang_ClassNotFoundException;
+utf *utf_java_lang_IllegalArgumentException;
+utf *utf_java_lang_IllegalMonitorStateException;
+
+utf *utf_java_lang_NullPointerException;
 
 utf* utf_java_lang_Void;
 utf* utf_java_lang_Boolean;
@@ -79,6 +93,10 @@ utf* utf_java_lang_Long;
 utf* utf_java_lang_Float;
 utf* utf_java_lang_Double;
 
+utf *utf_java_lang_StackTraceElement;
+utf *utf_java_lang_reflect_Constructor;
+utf *utf_java_lang_reflect_Field;
+utf *utf_java_lang_reflect_Method;
 utf *utf_java_util_Vector;
 
 utf *utf_InnerClasses;                  /* InnerClasses                       */
@@ -90,11 +108,29 @@ utf *utf_SourceFile;                    /* SourceFile                         */
 
 utf *utf_init;                          /* <init>                             */
 utf *utf_clinit;                        /* <clinit>                           */
+utf *utf_clone;                         /* clone                              */
 utf *utf_finalize;                      /* finalize                           */
+utf *utf_run;                           /* run                                */
+
+utf *utf_add;                           /* add                                */
+utf *utf_remove;                        /* remove                             */
+utf *utf_put;                           /* put                                */
+utf *utf_get;                           /* get                                */
+utf *utf_value;                         /* value                              */
 
-utf *utf_printStackTrace;
 utf *utf_fillInStackTrace;
+utf *utf_getSystemClassLoader;
 utf *utf_loadClass;
+utf *utf_printStackTrace;
+
+utf *utf_Z;                             /* Z                                  */
+utf *utf_B;                             /* B                                  */
+utf *utf_C;                             /* C                                  */
+utf *utf_S;                             /* S                                  */
+utf *utf_I;                             /* I                                  */
+utf *utf_J;                             /* J                                  */
+utf *utf_F;                             /* F                                  */
+utf *utf_D;                             /* D                                  */
 
 utf *utf_void__void;                    /* ()V                                */
 utf *utf_boolean__void;                 /* (Z)V                               */
@@ -105,8 +141,11 @@ utf *utf_int__void;                     /* (I)V                               */
 utf *utf_long__void;                    /* (J)V                               */
 utf *utf_float__void;                   /* (F)V                               */
 utf *utf_double__void;                  /* (D)V                               */
+
+utf *utf_void__java_lang_ClassLoader;   /* ()Ljava/lang/ClassLoader;          */
 utf *utf_void__java_lang_Object;        /* ()Ljava/lang/Object;               */
 utf *utf_void__java_lang_Throwable;     /* ()Ljava/lang/Throwable;            */
+utf *utf_java_lang_Object__java_lang_Object;
 utf *utf_java_lang_String__void;        /* (Ljava/lang/String;)V              */
 utf *utf_java_lang_String__java_lang_Class;
 utf *utf_java_lang_Throwable__void;     /* (Ljava/lang/Throwable;)V           */
@@ -122,8 +161,18 @@ utf *array_packagename;
 
 *******************************************************************************/
 
-void utf8_init(void)
+bool utf8_init(void)
 {
+#if defined(USE_THREADS)
+       /* create utf hashtable lock object */
+
+       lock_utf_hashtable = NEW(java_objectheader);
+
+# if defined(NATIVE_THREADS)
+       initObjectLock(lock_utf_hashtable);
+# endif
+#endif
+
        /* create utf-symbols for pointer comparison of frequently used strings */
 
        utf_java_lang_Object           = utf_new_char("java/lang/Object");
@@ -140,17 +189,33 @@ void utf8_init(void)
        utf_java_lang_Throwable        = utf_new_char(string_java_lang_Throwable);
        utf_java_lang_VMThrowable      = utf_new_char(string_java_lang_VMThrowable);
        utf_java_lang_Error            = utf_new_char(string_java_lang_Error);
-       utf_java_lang_Exception        = utf_new_char(string_java_lang_Exception);
 
        utf_java_lang_NoClassDefFoundError =
                utf_new_char(string_java_lang_NoClassDefFoundError);
 
+       utf_java_lang_LinkageError =
+               utf_new_char(string_java_lang_LinkageError);
+
+       utf_java_lang_NoSuchMethodError =
+               utf_new_char(string_java_lang_NoSuchMethodError);
+
        utf_java_lang_OutOfMemoryError =
                utf_new_char(string_java_lang_OutOfMemoryError);
 
+       utf_java_lang_Exception        = utf_new_char(string_java_lang_Exception);
+
        utf_java_lang_ClassNotFoundException =
                utf_new_char(string_java_lang_ClassNotFoundException);
 
+       utf_java_lang_IllegalArgumentException =
+               utf_new_char(string_java_lang_IllegalArgumentException);
+
+       utf_java_lang_IllegalMonitorStateException =
+               utf_new_char(string_java_lang_IllegalMonitorStateException);
+
+       utf_java_lang_NullPointerException =
+               utf_new_char(string_java_lang_NullPointerException);
+
        utf_java_lang_Void             = utf_new_char("java/lang/Void");
        utf_java_lang_Boolean          = utf_new_char("java/lang/Boolean");
        utf_java_lang_Byte             = utf_new_char("java/lang/Byte");
@@ -161,6 +226,14 @@ void utf8_init(void)
        utf_java_lang_Float            = utf_new_char("java/lang/Float");
        utf_java_lang_Double           = utf_new_char("java/lang/Double");
 
+       utf_java_lang_StackTraceElement =
+               utf_new_char("java/lang/StackTraceElement");
+
+       utf_java_lang_reflect_Constructor =
+               utf_new_char("java/lang/reflect/Constructor");
+
+       utf_java_lang_reflect_Field    = utf_new_char("java/lang/reflect/Field");
+       utf_java_lang_reflect_Method   = utf_new_char("java/lang/reflect/Method");
        utf_java_util_Vector           = utf_new_char("java/util/Vector");
 
        utf_InnerClasses               = utf_new_char("InnerClasses");
@@ -172,11 +245,29 @@ void utf8_init(void)
 
        utf_init                           = utf_new_char("<init>");
        utf_clinit                         = utf_new_char("<clinit>");
+       utf_clone                      = utf_new_char("clone");
        utf_finalize                   = utf_new_char("finalize");
+       utf_run                        = utf_new_char("run");
+
+       utf_add                        = utf_new_char("add");
+       utf_remove                     = utf_new_char("remove");
+       utf_put                        = utf_new_char("put");
+       utf_get                        = utf_new_char("get");
+       utf_value                      = utf_new_char("value");
 
        utf_printStackTrace            = utf_new_char("printStackTrace");
        utf_fillInStackTrace           = utf_new_char("fillInStackTrace");
        utf_loadClass                  = utf_new_char("loadClass");
+       utf_getSystemClassLoader       = utf_new_char("getSystemClassLoader");
+
+       utf_Z                          = utf_new_char("Z");
+       utf_B                          = utf_new_char("B");
+       utf_C                          = utf_new_char("C");
+       utf_S                          = utf_new_char("S");
+       utf_I                          = utf_new_char("I");
+       utf_J                          = utf_new_char("J");
+       utf_F                          = utf_new_char("F");
+       utf_D                          = utf_new_char("D");
 
        utf_void__void                 = utf_new_char("()V");
        utf_boolean__void              = utf_new_char("(Z)V");
@@ -189,6 +280,13 @@ void utf8_init(void)
        utf_double__void               = utf_new_char("(D)V");
        utf_void__java_lang_Object     = utf_new_char("()Ljava/lang/Object;");
        utf_void__java_lang_Throwable  = utf_new_char("()Ljava/lang/Throwable;");
+
+       utf_void__java_lang_ClassLoader =
+               utf_new_char("()Ljava/lang/ClassLoader;");
+
+       utf_java_lang_Object__java_lang_Object =
+               utf_new_char("(Ljava/lang/Object;)Ljava/lang/Object;");
+
        utf_java_lang_String__void     = utf_new_char("(Ljava/lang/String;)V");
 
        utf_java_lang_String__java_lang_Class =
@@ -199,6 +297,10 @@ void utf8_init(void)
        utf_not_named_yet              = utf_new_char("\t<not_named_yet>");
 
        array_packagename              = utf_new_char("\t<the array package>");
+
+       /* everything's ok */
+
+       return true;
 }
 
 
@@ -351,33 +453,26 @@ u4 unicode_hashkey(u2 *text, u2 len)
 
 *******************************************************************************/
 
-utf *utf_new_intern(const char *text, u2 length);
-
 utf *utf_new(const char *text, u2 length)
-{
-    utf *r;
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-    tables_lock();
-#endif
-
-    r = utf_new_intern(text, length);
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-    tables_unlock();
-#endif
-
-    return r;
-}
-
-
-utf *utf_new_intern(const char *text, u2 length)
 {
        u4 key;                             /* hashkey computed from utf-text     */
        u4 slot;                            /* slot in hashtable                  */
        utf *u;                             /* hashtable element                  */
        u2 i;
 
+       /* XXX REMOVE ME! after testing of course ;-) */
+       static int running = 0;
+       /* XXX REMOVE ME! */
+
+#if defined(USE_THREADS)
+       builtin_monitorenter(lock_utf_hashtable);
+#endif
+
+       /* XXX REMOVE ME! after testing of course ;-) */
+       assert(running == 0);
+       running = 1;
+       /* XXX REMOVE ME! */
+
 #ifdef STATISTICS
        if (opt_stat)
                count_utf_new++;
@@ -388,28 +483,40 @@ utf *utf_new_intern(const char *text, u2 length)
        u    = utf_hash.ptr[slot];
 
        /* search external hash chain for utf-symbol */
+
        while (u) {
                if (u->blength == length) {
-
                        /* compare text of hashtable elements */
+
                        for (i = 0; i < length; i++)
-                               if (text[i] != u->text[i]) goto nomatch;
+                               if (text[i] != u->text[i])
+                                       goto nomatch;
                        
-#ifdef STATISTICS
+#if defined(STATISTICS)
                        if (opt_stat)
                                count_utf_new_found++;
 #endif
 
                        /* symbol found in hashtable */
+
+                       /* XXX REMOVE ME! */
+                       running = 0;
+                       /* XXX REMOVE ME! */
+
+#if defined(USE_THREADS)
+                       builtin_monitorexit(lock_utf_hashtable);
+#endif
+
                        return u;
                }
+
        nomatch:
                u = u->hashlink; /* next element in external chain */
        }
 
-#ifdef STATISTICS
+#if defined(STATISTICS)
        if (opt_stat)
-               count_utf_len += sizeof(utf) + length;
+               count_utf_len += sizeof(utf) + length + 1;
 #endif
 
        /* location in hashtable found, create new utf element */
@@ -461,6 +568,14 @@ utf *utf_new_intern(const char *text, u2 length)
                utf_hash = newhash;
        }
 
+       /* XXX REMOVE ME! */
+       running = 0;
+       /* XXX REMOVE ME! */
+
+#if defined(USE_THREADS)
+       builtin_monitorexit(lock_utf_hashtable);
+#endif
+
        return u;
 }
 
@@ -647,7 +762,7 @@ u4 utf_strlen(utf *u)
                return 0;
        }
 
-       endpos = utf_end(u);
+       endpos = UTF_END(u);
        utf_ptr = u->text;
 
        while (utf_ptr < endpos) {
@@ -711,7 +826,7 @@ void utf_display(utf *u)
                return;
        }
 
-       endpos = utf_end(u);
+       endpos = UTF_END(u);
        utf_ptr = u->text;
 
        while (utf_ptr < endpos) {
@@ -743,7 +858,7 @@ void utf_display_classname(utf *u)
                return;
        }
 
-       endpos = utf_end(u);
+       endpos = UTF_END(u);
        utf_ptr = u->text;
 
        while (utf_ptr < endpos) {
@@ -775,7 +890,7 @@ void utf_sprint(char *buffer, utf *u)
                return;
        }
 
-       endpos = utf_end(u);
+       endpos = UTF_END(u);
        utf_ptr = u->text;
 
        while (utf_ptr < endpos) 
@@ -805,7 +920,7 @@ void utf_sprint_classname(char *buffer, utf *u)
                return;
        }
 
-       endpos = utf_end(u);
+       endpos = UTF_END(u);
        utf_ptr = u->text;
 
        while (utf_ptr < endpos) {
@@ -858,7 +973,7 @@ void utf_fprint(FILE *file, utf *u)
        if (!u)
                return;
 
-       endpos = utf_end(u);
+       endpos = UTF_END(u);
        utf_ptr = u->text;
 
        while (utf_ptr < endpos) { 
@@ -885,7 +1000,7 @@ void utf_fprint_classname(FILE *file, utf *u)
     if (!u)
                return;
 
-       endpos = utf_end(u);
+       endpos = UTF_END(u);
        utf_ptr = u->text;
 
        while (utf_ptr < endpos) { 
@@ -908,7 +1023,7 @@ void utf_fprint_classname(FILE *file, utf *u)
 
 *******************************************************************************/
 
-static unsigned long min_codepoint[6] = {0,1L<<7,1L<<11,1L<<16,1L<<21,1L<<26};
+/*  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)
 {
@@ -951,11 +1066,8 @@ bool is_valid_utf(char *utf_ptr, char *end_pos)
                } else {
                        /* Sun Java seems to allow overlong UTF-8 encodings */
                        
-                       if (v < min_codepoint[len]) { /* overlong UTF-8 */
-                               if (!opt_liberalutf)
-                                       fprintf(stderr,"WARNING: Overlong UTF-8 sequence found.\n");
-                               /* XXX change this to panic? */
-                       }
+                       /* if (v < min_codepoint[len]) */
+                               /* XXX throw exception? */
                }
 
                /* surrogates in UTF-8 seem to be allowed in Java classfiles */
@@ -999,7 +1111,7 @@ bool is_valid_name(char *utf_ptr, char *end_pos)
 
 bool is_valid_name_utf(utf *u)
 {
-       return is_valid_name(u->text,utf_end(u));
+       return is_valid_name(u->text, UTF_END(u));
 }