/* src/vm/string.c - java.lang.String related functions
- 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, 2007 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.
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
-
- Authors: Reinhard Grafl
- Roman Obermaisser
- Andreas Krall
-
- Changes: Christian Thalinger
-
- $Id: string.c 3888 2005-12-05 22:08:45Z twisti $
+ $Id: string.c 7522 2007-03-14 21:54:49Z twisti $
*/
+#include "config.h"
+
#include <assert.h>
-#include "config.h"
#include "vm/types.h"
#include "vm/global.h"
#include "mm/memory.h"
+
+#include "native/jni.h"
+
#include "native/include/java_lang_String.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#else
+# include "threads/none/lock.h"
+#endif
+
+#include "vm/builtin.h"
#include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
#include "vm/stringlocal.h"
-#include "vm/utf8.h"
+
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
+#include "vmcore/utf8.h"
/* global variables ***********************************************************/
hashtable hashtable_string; /* hashtable for javastrings */
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
static java_objectheader *lock_hashtable_string;
#endif
-/* global string definitions **************************************************/
-
-/* exception/error super class */
-
-const char *string_java_lang_Throwable =
- "java/lang/Throwable";
-
-const char *string_java_lang_VMThrowable =
- "java/lang/VMThrowable";
-
-
-/* specify some exception strings for code generation */
-
-const char *string_java_lang_ArithmeticException =
- "java/lang/ArithmeticException";
-
-const char *string_java_lang_ArithmeticException_message =
- "/ by zero";
-
-const char *string_java_lang_ArrayIndexOutOfBoundsException =
- "java/lang/ArrayIndexOutOfBoundsException";
-
-const char *string_java_lang_ArrayStoreException =
- "java/lang/ArrayStoreException";
-
-const char *string_java_lang_ClassCastException =
- "java/lang/ClassCastException";
-
-const char *string_java_lang_ClassNotFoundException =
- "java/lang/ClassNotFoundException";
-
-const char *string_java_lang_CloneNotSupportedException =
- "java/lang/CloneNotSupportedException";
-
-const char *string_java_lang_Exception =
- "java/lang/Exception";
-
-const char *string_java_lang_IllegalAccessException =
- "java/lang/IllegalAccessException";
-
-const char *string_java_lang_IllegalArgumentException =
- "java/lang/IllegalArgumentException";
-
-const char *string_java_lang_IllegalMonitorStateException =
- "java/lang/IllegalMonitorStateException";
-
-const char *string_java_lang_IndexOutOfBoundsException =
- "java/lang/IndexOutOfBoundsException";
-
-const char *string_java_lang_InstantiationException =
- "java/lang/InstantiationException";
-
-const char *string_java_lang_InterruptedException =
- "java/lang/InterruptedException";
-
-const char *string_java_lang_NegativeArraySizeException =
- "java/lang/NegativeArraySizeException";
-
-const char *string_java_lang_NoSuchFieldException =
- "java/lang/NoSuchFieldException";
-
-const char *string_java_lang_NoSuchMethodException =
- "java/lang/NoSuchMethodException";
-
-const char *string_java_lang_NullPointerException =
- "java/lang/NullPointerException";
-
-const char *string_java_lang_reflect_InvocationTargetException =
- "java/lang/reflect/InvocationTargetException";
-
-
-/* specify some error strings for code generation */
-
-const char *string_java_lang_AbstractMethodError =
- "java/lang/AbstractMethodError";
-
-const char *string_java_lang_ClassCircularityError =
- "java/lang/ClassCircularityError";
-
-const char *string_java_lang_ClassFormatError =
- "java/lang/ClassFormatError";
-
-const char *string_java_lang_Error =
- "java/lang/Error";
-
-const char *string_java_lang_ExceptionInInitializerError =
- "java/lang/ExceptionInInitializerError";
-
-const char *string_java_lang_IncompatibleClassChangeError =
- "java/lang/IncompatibleClassChangeError";
-
-const char *string_java_lang_InstantiationError =
- "java/lang/InstantiationError";
-
-const char *string_java_lang_InternalError =
- "java/lang/InternalError";
-
-const char *string_java_lang_LinkageError =
- "java/lang/LinkageError";
-
-const char *string_java_lang_NoClassDefFoundError =
- "java/lang/NoClassDefFoundError";
-
-const char *string_java_lang_NoSuchFieldError =
- "java/lang/NoSuchFieldError";
-
-const char *string_java_lang_NoSuchMethodError =
- "java/lang/NoSuchMethodError";
-
-const char *string_java_lang_OutOfMemoryError =
- "java/lang/OutOfMemoryError";
-
-const char *string_java_lang_UnsatisfiedLinkError =
- "java/lang/UnsatisfiedLinkError";
-
-const char *string_java_lang_UnsupportedClassVersionError =
- "java/lang/UnsupportedClassVersionError";
-
-const char *string_java_lang_VerifyError =
- "java/lang/VerifyError";
-
-const char *string_java_lang_VirtualMachineError =
- "java/lang/VirtualMachineError";
-
-
/* string_init *****************************************************************
Initialize the string hashtable lock.
hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE);
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
/* create string hashtable lock object */
lock_hashtable_string = NEW(java_objectheader);
-# if defined(NATIVE_THREADS)
- initObjectLock(lock_hashtable_string);
-# endif
+ lock_init_object_lock(lock_hashtable_string);
#endif
/* everything's ok */
}
+/* javastring_new_from_utf_buffer **********************************************
+
+ Create a new object of type java/lang/String with the text from
+ the specified utf8 buffer.
+
+ IN:
+ buffer.......points to first char in the buffer
+ blength......number of bytes to read from the buffer
+
+ RETURN VALUE:
+ the java.lang.String object, or
+ NULL if an exception has been thrown
+
+*******************************************************************************/
+
+java_objectheader *javastring_new_from_utf_buffer(const char *buffer, u4 blength)
+{
+ const char *utf_ptr; /* current utf character in utf string */
+ u4 utflength; /* length of utf-string if uncompressed */
+ java_objectheader *o;
+ java_lang_String *s; /* result-string */
+ java_chararray *a;
+ u4 i;
+
+ assert(buffer);
+
+ utflength = utf_get_number_of_u2s_for_buffer(buffer,blength);
+
+ o = builtin_new(class_java_lang_String);
+ a = builtin_newarray_char(utflength);
+
+ /* javastring or character-array could not be created */
+
+ if ((o == NULL) || (a == NULL))
+ return NULL;
+
+ /* decompress utf-string */
+
+ utf_ptr = buffer;
+
+ for (i = 0; i < utflength; i++)
+ a->data[i] = utf_nextu2((char **) &utf_ptr);
+
+ /* set fields of the javastring-object */
+
+ s = (java_lang_String *) o;
+
+ s->value = a;
+ s->offset = 0;
+ s->count = utflength;
+
+ return o;
+}
+
+
+/* javastring_safe_new_from_utf8 ***********************************************
+
+ Create a new object of type java/lang/String with the text from
+ the specified UTF-8 string. This function is safe for invalid UTF-8.
+ (Invalid characters will be replaced by U+fffd.)
+
+ IN:
+ text.........the UTF-8 string, zero-terminated.
+
+ RETURN VALUE:
+ the java.lang.String object, or
+ NULL if an exception has been thrown
+
+*******************************************************************************/
+
+java_objectheader *javastring_safe_new_from_utf8(const char *text)
+{
+ java_objectheader *o;
+ java_chararray *a;
+ java_lang_String *s;
+ s4 nbytes;
+ s4 len;
+
+ assert(text);
+
+ /* Get number of bytes. We need this to completely emulate the messy */
+ /* behaviour of the RI. :( */
+
+ nbytes = strlen(text);
+
+ /* calculate number of Java characters */
+
+ len = utf8_safe_number_of_u2s(text, nbytes);
+
+ /* allocate the String object and the char array */
+
+ o = builtin_new(class_java_lang_String);
+ a = builtin_newarray_char(len);
+
+ /* javastring or character-array could not be created? */
+
+ if ((o == NULL) || (a == NULL))
+ return NULL;
+
+ /* decompress UTF-8 string */
+
+ utf8_safe_convert_to_u2s(text, nbytes, a->data);
+
+ /* set fields of the String object */
+
+ s = (java_lang_String *) o;
+
+ s->value = a;
+ s->offset = 0;
+ s->count = len;
+
+ return o;
+}
+
+
+/* javastring_new_from_utf_string **********************************************
+
+ Create a new object of type java/lang/String with the text from
+ the specified zero-terminated utf8 string.
+
+ IN:
+ buffer.......points to first char in the buffer
+ blength......number of bytes to read from the buffer
+
+ RETURN VALUE:
+ the java.lang.String object, or
+ NULL if an exception has been thrown
+
+*******************************************************************************/
+
+java_objectheader *javastring_new_from_utf_string(const char *utfstr)
+{
+ assert(utfstr);
+
+ return javastring_new_from_utf_buffer(utfstr, strlen(utfstr));
+}
+
+
/* javastring_new **************************************************************
creates a new object of type java/lang/String with the text of
*******************************************************************************/
-java_lang_String *javastring_new(utf *u)
+java_objectheader *javastring_new(utf *u)
{
char *utf_ptr; /* current utf character in utf string */
u4 utflength; /* length of utf-string if uncompressed */
- java_lang_String *s; /* result-string */
- java_chararray *a;
+ java_objectheader *o;
+ java_chararray *a;
+ java_lang_String *s;
s4 i;
- if (!u) {
- *exceptionptr = new_nullpointerexception();
+ if (u == NULL) {
+ exceptions_throw_nullpointerexception();
return NULL;
}
utf_ptr = u->text;
- utflength = utf_strlen(u);
+ utflength = utf_get_number_of_u2s(u);
- s = (java_lang_String *) builtin_new(class_java_lang_String);
+ o = builtin_new(class_java_lang_String);
a = builtin_newarray_char(utflength);
/* javastring or character-array could not be created */
- if (!a || !s)
+
+ if ((o == NULL) || (a == NULL))
return NULL;
/* decompress utf-string */
+
for (i = 0; i < utflength; i++)
a->data[i] = utf_nextu2(&utf_ptr);
/* set fields of the javastring-object */
+
+ s = (java_lang_String *) o;
+
s->value = a;
s->offset = 0;
s->count = utflength;
- return s;
+ return o;
}
+
/* javastring_new_slash_to_dot *************************************************
creates a new object of type java/lang/String with the text of
*******************************************************************************/
-java_lang_String *javastring_new_slash_to_dot(utf *u)
+java_objectheader *javastring_new_slash_to_dot(utf *u)
{
char *utf_ptr; /* current utf character in utf string */
u4 utflength; /* length of utf-string if uncompressed */
- java_lang_String *s; /* result-string */
- java_chararray *a;
+ java_objectheader *o;
+ java_chararray *a;
+ java_lang_String *s;
s4 i;
u2 ch;
- if (!u) {
- *exceptionptr = new_nullpointerexception();
+ if (u == NULL) {
+ exceptions_throw_nullpointerexception();
return NULL;
}
utf_ptr = u->text;
- utflength = utf_strlen(u);
+ utflength = utf_get_number_of_u2s(u);
- s = (java_lang_String *) builtin_new(class_java_lang_String);
+ o = builtin_new(class_java_lang_String);
a = builtin_newarray_char(utflength);
/* javastring or character-array could not be created */
- if (!a || !s)
+ if ((o == NULL) || (a == NULL))
return NULL;
/* decompress utf-string */
+
for (i = 0; i < utflength; i++) {
ch = utf_nextu2(&utf_ptr);
if (ch == '/')
}
/* set fields of the javastring-object */
+
+ s = (java_lang_String *) o;
+
s->value = a;
s->offset = 0;
s->count = utflength;
- return s;
+ return o;
}
-/* javastring_new_char *********************************************************
+/* javastring_new_from_ascii ***************************************************
+
+ creates a new java/lang/String object which contains the given ASCII
+ C-string converted to UTF-16.
- creates a new java/lang/String object which contains the convertet
- C-string passed via text.
+ IN:
+ text.........string of ASCII characters
- return: the object pointer or NULL if memory is exhausted.
+ RETURN VALUE:
+ the java.lang.String object, or
+ NULL if an exception has been thrown.
*******************************************************************************/
-java_lang_String *javastring_new_char(const char *text)
+java_objectheader *javastring_new_from_ascii(const char *text)
{
s4 i;
s4 len; /* length of the string */
- java_lang_String *s; /* result-string */
- java_chararray *a;
+ java_objectheader *o;
+ java_lang_String *s;
+ java_chararray *a;
- if (!text) {
- *exceptionptr = new_nullpointerexception();
+ if (text == NULL) {
+ exceptions_throw_nullpointerexception();
return NULL;
}
len = strlen(text);
- s = (java_lang_String *) builtin_new(class_java_lang_String);
+ o = builtin_new(class_java_lang_String);
a = builtin_newarray_char(len);
/* javastring or character-array could not be created */
- if (!a || !s)
+
+ if ((o == NULL) || (a == NULL))
return NULL;
/* copy text */
+
for (i = 0; i < len; i++)
a->data[i] = text[i];
/* set fields of the javastring-object */
+
+ s = (java_lang_String *) o;
+
s->value = a;
s->offset = 0;
s->count = len;
- return s;
+ return o;
}
*******************************************************************************/
-utf *javastring_toutf(java_lang_String *string, bool isclassname)
+utf *javastring_toutf(java_objectheader *string, bool isclassname)
{
- java_lang_String *str = (java_lang_String *) string;
-
- return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
-}
-
-
-/* javastring_strlen ***********************************************************
+ java_lang_String *s;
- Returns the length of the Java string.
-
-*******************************************************************************/
+ s = (java_lang_String *) string;
-s4 javastring_strlen(java_objectheader *so)
-{
- java_lang_String *s = (java_lang_String *) so;
-
- if (!s)
- return 0;
+ if (s == NULL)
+ return utf_null;
- return s->count;
+ return utf_new_u2(s->value->data + s->offset, s->count, isclassname);
}
u4 slot;
u2 i;
-#if defined(USE_THREADS)
- builtin_monitorenter(lock_hashtable_string);
-#endif
+ LOCK_MONITOR_ENTER(lock_hashtable_string);
/* find location in hashtable */
if (!copymode)
mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
-#if defined(USE_THREADS)
- builtin_monitorexit(lock_hashtable_string);
-#endif
+ LOCK_MONITOR_EXIT(lock_hashtable_string);
return (java_objectheader *) js;
}
primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
stringdata->header.size = length;
- /* XXX TWISTI: is this necessary? */
- if (!class_java_lang_String)
- class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
-
assert(class_java_lang_String);
assert(class_java_lang_String->state & CLASS_LOADED);
/* if we use eager loading, we have to check loaded String class */
if (opt_eager)
- list_addfirst(&unlinkedclasses, class_java_lang_String);
+ list_add_first(&unlinkedclasses, class_java_lang_String);
/* create new javastring */
js = NEW(java_lang_String);
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- initObjectLock(&js->header);
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ size_string += sizeof(java_lang_String);
+#endif
+
+#if defined(ENABLE_THREADS)
+ lock_init_object_lock(&js->header);
#endif
js->header.vftbl = class_java_lang_String->vftbl;
/* create new literalstring */
s = NEW(literalstring);
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ size_string += sizeof(literalstring);
+#endif
+
s->hashlink = hashtable_string.ptr[slot];
s->string = (java_objectheader *) js;
hashtable_string.ptr[slot] = s;
hashtable_string = newhash;
}
-#if defined(USE_THREADS)
- builtin_monitorexit(lock_hashtable_string);
-#endif
+ LOCK_MONITOR_EXIT(lock_hashtable_string);
return (java_objectheader *) js;
}
u4 i;
utf_ptr = u->text;
- utflength = utf_strlen(u);
+ utflength = utf_get_number_of_u2s(u);
/* allocate memory */
a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
*******************************************************************************/
-void literalstring_free(java_objectheader* sobj)
+void literalstring_free(java_objectheader* string)
{
java_lang_String *s;
java_chararray *a;
- s = (java_lang_String *) sobj;
+ s = (java_lang_String *) string;
a = s->value;
/* dispose memory of java.lang.String object */
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/