X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fstring.c;h=f24e411e021c0c35c86777787ab5dbf063f56f98;hb=b76e356b0af200d2568e6fc55e82e233f1808eb9;hp=306c50bbc89399df0c971809f875d8b969e8e8fc;hpb=d8572646e8104542a3e010813242b450194ec160;p=cacao.git diff --git a/src/vm/string.c b/src/vm/string.c index 306c50bbc..f24e411e0 100644 --- a/src/vm/string.c +++ b/src/vm/string.c @@ -1,9 +1,7 @@ /* 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, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -19,36 +17,41 @@ 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. - - Contact: cacao@complang.tuwien.ac.at - - Authors: Reinhard Grafl - Roman Obermaisser - Andreas Krall - - Changes: Christian Thalinger - - $Id: string.c 3832 2005-12-01 23:19:29Z twisti $ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ +#include "config.h" + #include -#include "config.h" +#include "vmcore/system.h" + #include "vm/types.h" #include "vm/global.h" #include "mm/memory.h" + +#include "native/jni.h" +#include "native/llni.h" + #include "native/include/java_lang_String.h" + +#include "threads/lock-common.h" + +#include "vm/array.h" +#include "vm/builtin.h" #include "vm/exceptions.h" -#include "vm/loader.h" -#include "vm/options.h" +#include "vm/primitive.h" #include "vm/stringlocal.h" -#include "vm/utf8.h" +#include "vm/vm.h" + +#include "vmcore/options.h" +#include "vmcore/statistics.h" +#include "vmcore/utf8.h" /* global variables ***********************************************************/ @@ -59,207 +62,232 @@ hashtable hashtable_string; /* hashtable for javastrings */ -#if defined(USE_THREADS) -static java_objectheader *lock_hashtable_string; +#if defined(ENABLE_THREADS) +static java_object_t *lock_hashtable_string; #endif -/* global string definitions **************************************************/ +/* XXX preliminary typedef, will be removed once string.c and utf8.c are + unified. */ -/* exception/error super class */ +#if defined(ENABLE_HANDLES) +typedef heap_java_lang_String heapstring_t; +#else +typedef java_lang_String heapstring_t; +#endif -const char *string_java_lang_Throwable = - "java/lang/Throwable"; -const char *string_java_lang_VMThrowable = - "java/lang/VMThrowable"; +/* string_init ***************************************************************** + Initialize the string hashtable lock. -/* specify some exception strings for code generation */ +*******************************************************************************/ -const char *string_java_lang_ArithmeticException = - "java/lang/ArithmeticException"; +bool string_init(void) +{ + TRACESUBSYSTEMINITIALIZATION("string_init"); -const char *string_java_lang_ArithmeticException_message = - "/ by zero"; + /* create string (javastring) hashtable */ -const char *string_java_lang_ArrayIndexOutOfBoundsException = - "java/lang/ArrayIndexOutOfBoundsException"; + hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE); -const char *string_java_lang_ArrayStoreException = - "java/lang/ArrayStoreException"; +#if defined(ENABLE_THREADS) + /* create string hashtable lock object */ -const char *string_java_lang_ClassCastException = - "java/lang/ClassCastException"; + lock_hashtable_string = NEW(java_object_t); -const char *string_java_lang_ClassNotFoundException = - "java/lang/ClassNotFoundException"; + LOCK_INIT_OBJECT_LOCK(lock_hashtable_string); +#endif -const char *string_java_lang_CloneNotSupportedException = - "java/lang/CloneNotSupportedException"; + /* everything's ok */ -const char *string_java_lang_Exception = - "java/lang/Exception"; + return true; +} -const char *string_java_lang_IllegalAccessException = - "java/lang/IllegalAccessException"; -const char *string_java_lang_IllegalArgumentException = - "java/lang/IllegalArgumentException"; +/* stringtable_update ********************************************************** -const char *string_java_lang_IllegalMonitorStateException = - "java/lang/IllegalMonitorStateException"; + Traverses the javastring hashtable and sets the vftbl-entries of + javastrings which were temporarily set to NULL, because + java.lang.Object was not yet loaded. -const char *string_java_lang_IndexOutOfBoundsException = - "java/lang/IndexOutOfBoundsException"; +*******************************************************************************/ + +void stringtable_update(void) +{ + heapstring_t *js; + java_chararray_t *a; + literalstring *s; /* hashtable entry */ + int i; -const char *string_java_lang_InstantiationException = - "java/lang/InstantiationException"; + for (i = 0; i < hashtable_string.size; i++) { + s = hashtable_string.ptr[i]; + if (s) { + while (s) { + js = (heapstring_t *) s->string; + + if ((js == NULL) || (js->value == NULL)) { + /* error in hashtable found */ -const char *string_java_lang_InterruptedException = - "java/lang/InterruptedException"; + vm_abort("stringtable_update: invalid literalstring in hashtable"); + } -const char *string_java_lang_NegativeArraySizeException = - "java/lang/NegativeArraySizeException"; + a = js->value; -const char *string_java_lang_NoSuchFieldException = - "java/lang/NoSuchFieldException"; + if (!js->header.vftbl) + /* vftbl of javastring is NULL */ + js->header.vftbl = class_java_lang_String->vftbl; -const char *string_java_lang_NoSuchMethodException = - "java/lang/NoSuchMethodException"; + if (!a->header.objheader.vftbl) + /* vftbl of character-array is NULL */ + a->header.objheader.vftbl = + primitive_arrayclass_get_by_type(ARRAYTYPE_CHAR)->vftbl; -const char *string_java_lang_NullPointerException = - "java/lang/NullPointerException"; + /* follow link in external hash chain */ + s = s->hashlink; + } + } + } +} -const char *string_java_lang_reflect_InvocationTargetException = - "java/lang/reflect/InvocationTargetException"; +/* javastring_new_from_utf_buffer ********************************************** -/* specify some error strings for code generation */ + Create a new object of type java/lang/String with the text from + the specified utf8 buffer. -const char *string_java_lang_AbstractMethodError = - "java/lang/AbstractMethodError"; + IN: + buffer.......points to first char in the buffer + blength......number of bytes to read from the buffer -const char *string_java_lang_ClassCircularityError = - "java/lang/ClassCircularityError"; + RETURN VALUE: + the java.lang.String object, or + NULL if an exception has been thrown -const char *string_java_lang_ClassFormatError = - "java/lang/ClassFormatError"; +*******************************************************************************/ -const char *string_java_lang_Error = - "java/lang/Error"; +static java_handle_t *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_handle_t *o; + java_lang_String *s; /* result-string */ + java_handle_chararray_t *a; + u4 i; -const char *string_java_lang_ExceptionInInitializerError = - "java/lang/ExceptionInInitializerError"; + assert(buffer); -const char *string_java_lang_IncompatibleClassChangeError = - "java/lang/IncompatibleClassChangeError"; + utflength = utf_get_number_of_u2s_for_buffer(buffer,blength); -const char *string_java_lang_InstantiationError = - "java/lang/InstantiationError"; + o = builtin_new(class_java_lang_String); + a = builtin_newarray_char(utflength); -const char *string_java_lang_InternalError = - "java/lang/InternalError"; + /* javastring or character-array could not be created */ -const char *string_java_lang_LinkageError = - "java/lang/LinkageError"; + if ((o == NULL) || (a == NULL)) + return NULL; -const char *string_java_lang_NoClassDefFoundError = - "java/lang/NoClassDefFoundError"; + /* decompress utf-string */ -const char *string_java_lang_NoSuchFieldError = - "java/lang/NoSuchFieldError"; + utf_ptr = buffer; -const char *string_java_lang_NoSuchMethodError = - "java/lang/NoSuchMethodError"; + for (i = 0; i < utflength; i++) + LLNI_array_direct(a, i) = utf_nextu2((char **) &utf_ptr); + + /* set fields of the javastring-object */ -const char *string_java_lang_OutOfMemoryError = - "java/lang/OutOfMemoryError"; + s = (java_lang_String *) o; -const char *string_java_lang_UnsatisfiedLinkError = - "java/lang/UnsatisfiedLinkError"; + LLNI_field_set_ref(s, value , a); + LLNI_field_set_val(s, offset, 0); + LLNI_field_set_val(s, count , utflength); -const char *string_java_lang_UnsupportedClassVersionError = - "java/lang/UnsupportedClassVersionError"; + return o; +} -const char *string_java_lang_VerifyError = - "java/lang/VerifyError"; -const char *string_java_lang_VirtualMachineError = - "java/lang/VirtualMachineError"; +/* 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.) -/* string_init ***************************************************************** + IN: + text.........the UTF-8 string, zero-terminated. - Initialize the string hashtable lock. + RETURN VALUE: + the java.lang.String object, or + NULL if an exception has been thrown *******************************************************************************/ -bool string_init(void) +java_handle_t *javastring_safe_new_from_utf8(const char *text) { - /* create string (javastring) hashtable */ + java_handle_t *o; + java_handle_chararray_t *a; + java_lang_String *s; + s4 nbytes; + s4 len; - hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE); + if (text == NULL) + return NULL; -#if defined(USE_THREADS) - /* create string hashtable lock object */ + /* Get number of bytes. We need this to completely emulate the messy */ + /* behaviour of the RI. :( */ - lock_hashtable_string = NEW(java_objectheader); + nbytes = strlen(text); -# if defined(NATIVE_THREADS) - initObjectLock(lock_hashtable_string); -# endif -#endif + /* calculate number of Java characters */ - /* everything's ok */ + len = utf8_safe_number_of_u2s(text, nbytes); - return true; -} + /* allocate the String object and the char array */ + o = builtin_new(class_java_lang_String); + a = builtin_newarray_char(len); -/* stringtable_update ********************************************************** + /* javastring or character-array could not be created? */ - Traverses the javastring hashtable and sets the vftbl-entries of - javastrings which were temporarily set to NULL, because - java.lang.Object was not yet loaded. + if ((o == NULL) || (a == NULL)) + return NULL; -*******************************************************************************/ - -void stringtable_update(void) -{ - java_lang_String *js; - java_chararray *a; - literalstring *s; /* hashtable entry */ - int i; + /* decompress UTF-8 string */ - for (i = 0; i < hashtable_string.size; i++) { - s = hashtable_string.ptr[i]; - if (s) { - while (s) { - - js = (java_lang_String *) s->string; - - if (!js || !js->value) { - /* error in hashtable found */ - log_text("invalid literalstring in hashtable"); - assert(0); - } + utf8_safe_convert_to_u2s(text, nbytes, LLNI_array_data(a)); - a = js->value; + /* set fields of the String object */ - if (!js->header.vftbl) - /* vftbl of javastring is NULL */ - js->header.vftbl = class_java_lang_String->vftbl; + s = (java_lang_String *) o; - if (!a->header.objheader.vftbl) - /* vftbl of character-array is NULL */ - a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl; + LLNI_field_set_ref(s, value , a); + LLNI_field_set_val(s, offset, 0); + LLNI_field_set_val(s, count , len); - /* follow link in external hash chain */ - s = s->hashlink; - } - } - } + 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_handle_t *javastring_new_from_utf_string(const char *utfstr) +{ + assert(utfstr); + + return javastring_new_from_utf_buffer(utfstr, strlen(utfstr)); } @@ -272,41 +300,48 @@ void stringtable_update(void) *******************************************************************************/ -java_lang_String *javastring_new(utf *u) +java_handle_t *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_handle_t *o; + java_handle_chararray_t *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); + LLNI_array_direct(a, i) = utf_nextu2(&utf_ptr); /* set fields of the javastring-object */ - s->value = a; - s->offset = 0; - s->count = utflength; - return s; + s = (java_lang_String *) o; + + LLNI_field_set_ref(s, value , a); + LLNI_field_set_val(s, offset, 0); + LLNI_field_set_val(s, count , utflength); + + return o; } + /* javastring_new_slash_to_dot ************************************************* creates a new object of type java/lang/String with the text of @@ -316,87 +351,103 @@ java_lang_String *javastring_new(utf *u) *******************************************************************************/ -java_lang_String *javastring_new_slash_to_dot(utf *u) +java_handle_t *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_handle_t *o; + java_handle_chararray_t *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 == '/') ch = '.'; - a->data[i] = ch; + LLNI_array_direct(a, i) = ch; } /* set fields of the javastring-object */ - s->value = a; - s->offset = 0; - s->count = utflength; - return s; + s = (java_lang_String *) o; + + LLNI_field_set_ref(s, value , a); + LLNI_field_set_val(s, offset, 0); + LLNI_field_set_val(s, count , utflength); + + return o; } -/* javastring_new_char ********************************************************* +/* javastring_new_from_ascii *************************************************** - creates a new java/lang/String object which contains the convertet - C-string passed via text. + creates a new java/lang/String object which contains the given ASCII + C-string converted to UTF-16. - return: the object pointer or NULL if memory is exhausted. + IN: + text.........string of ASCII characters + + 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_handle_t *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_handle_t *o; + java_lang_String *s; + java_handle_chararray_t *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]; + LLNI_array_direct(a, i) = text[i]; /* set fields of the javastring-object */ - s->value = a; - s->offset = 0; - s->count = len; - return s; + s = (java_lang_String *) o; + + LLNI_field_set_ref(s, value , a); + LLNI_field_set_val(s, offset, 0); + LLNI_field_set_val(s, count , len); + + return o; } @@ -410,25 +461,30 @@ java_lang_String *javastring_new_char(const char *text) *******************************************************************************/ -char *javastring_tochar(java_objectheader *so) +char *javastring_tochar(java_handle_t *so) { - java_lang_String *s = (java_lang_String *) so; - java_chararray *a; + java_lang_String *s = (java_lang_String *) so; + java_handle_chararray_t *a; + int32_t count; + int32_t offset; char *buf; s4 i; if (!s) return ""; - a = s->value; + LLNI_field_get_ref(s, value, a); if (!a) return ""; - buf = MNEW(char, s->count + 1); + LLNI_field_get_val(s, count, count); + LLNI_field_get_val(s, offset, offset); + + buf = MNEW(char, count + 1); - for (i = 0; i < s->count; i++) - buf[i] = a->data[s->offset + i]; + for (i = 0; i < count; i++) + buf[i] = LLNI_array_direct(a, offset + i); buf[i] = '\0'; @@ -442,53 +498,50 @@ char *javastring_tochar(java_objectheader *so) *******************************************************************************/ -utf *javastring_toutf(java_lang_String *string, bool isclassname) +utf *javastring_toutf(java_handle_t *string, bool isclassname) { - java_lang_String *str = (java_lang_String *) string; + java_lang_String *s; + java_handle_chararray_t *value; + int32_t count; + int32_t offset; - return utf_new_u2(str->value->data + str->offset, str->count, isclassname); -} + s = (java_lang_String *) string; + if (s == NULL) + return utf_null; -/* javastring_strlen *********************************************************** + LLNI_field_get_ref(s, value, value); - Returns the length of the Java string. - -*******************************************************************************/ + if (value == NULL) + return utf_null; -s4 javastring_strlen(java_objectheader *so) -{ - java_lang_String *s = (java_lang_String *) so; - - if (!s) - return 0; + LLNI_field_get_val(s, count, count); + LLNI_field_get_val(s, offset, offset); - return s->count; + return utf_new_u2(LLNI_array_data(value) + offset, count, isclassname); } /* literalstring_u2 ************************************************************ - Searches for the javastring with the specified u2-array in the + Searches for the literalstring with the specified u2-array in the string hashtable, if there is no such string a new one is created. If copymode is true a copy of the u2-array is made. *******************************************************************************/ -java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, - bool copymode) +static java_object_t *literalstring_u2(java_chararray_t *a, u4 length, + u4 offset, bool copymode) { literalstring *s; /* hashtable element */ - java_lang_String *js; /* u2-array wrapped in javastring */ - java_chararray *stringdata; /* copy of u2-array */ + heapstring_t *js; /* u2-array wrapped in javastring */ + java_chararray_t *ca; /* copy of u2-array */ u4 key; u4 slot; u2 i; -#if defined(USE_THREADS) - builtin_monitorenter(lock_hashtable_string); -#endif + LOCK_MONITOR_ENTER(lock_hashtable_string); /* find location in hashtable */ @@ -497,7 +550,7 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, s = hashtable_string.ptr[slot]; while (s) { - js = (java_lang_String *) s->string; + js = (heapstring_t *) s->string; if (length == js->count) { /* compare text */ @@ -509,13 +562,11 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, /* string already in hashtable, free memory */ if (!copymode) - mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10); + mem_free(a, sizeof(java_chararray_t) + 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; + return (java_object_t *) js; } nomatch: @@ -525,52 +576,54 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, if (copymode) { /* create copy of u2-array for new javastring */ - u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10; - stringdata = mem_alloc(arraysize); -/* memcpy(stringdata, a, arraysize); */ - memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader)); - memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10); + u4 arraysize = sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10; + ca = mem_alloc(arraysize); +/* memcpy(ca, a, arraysize); */ + memcpy(&(ca->header), &(a->header), sizeof(java_array_t)); + memcpy(&(ca->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10); } else { - stringdata = a; + ca = a; } /* location in hashtable found, complete arrayheader */ - stringdata->header.objheader.vftbl = - 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); + ca->header.objheader.vftbl = + primitive_arrayclass_get_by_type(ARRAYTYPE_CHAR)->vftbl; + ca->header.size = length; assert(class_java_lang_String); - assert(class_java_lang_String->loaded); - - /* if we use eager loading, we have to check loaded String class */ - - if (opt_eager) - list_addfirst(&unlinkedclasses, class_java_lang_String); + assert(class_java_lang_String->state & CLASS_LOADED); /* create new javastring */ - js = NEW(java_lang_String); + js = NEW(heapstring_t); + +#if defined(ENABLE_STATISTICS) + if (opt_stat) + size_string += sizeof(heapstring_t); +#endif -#if defined(USE_THREADS) && defined(NATIVE_THREADS) - initObjectLock(&js->header); +#if defined(ENABLE_THREADS) + lock_init_object_lock(&js->header); #endif js->header.vftbl = class_java_lang_String->vftbl; - js->value = stringdata; + js->value = ca; js->offset = 0; js->count = length; /* 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; + s->string = (java_object_t *) js; hashtable_string.ptr[slot] = s; /* update number of hashtable entries */ @@ -583,11 +636,11 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, /* reorganization of hashtable, average length of the external chains is approx. 2 */ - u4 i; - literalstring *s; - literalstring *nexts; - java_lang_String *tmpjs; - hashtable newhash; /* the new hashtable */ + u4 i; + literalstring *s; + literalstring *nexts; + heapstring_t *tmpjs; + hashtable newhash; /* the new hashtable */ /* create new hashtable, double the size */ @@ -601,7 +654,7 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, while (s) { nexts = s->hashlink; - tmpjs = (java_lang_String *) s->string; + tmpjs = (heapstring_t *) s->string; slot = unicode_hashkey(tmpjs->value->data, tmpjs->count) & (newhash.size - 1); s->hashlink = newhash.ptr[slot]; @@ -618,34 +671,32 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, hashtable_string = newhash; } -#if defined(USE_THREADS) - builtin_monitorexit(lock_hashtable_string); -#endif + LOCK_MONITOR_EXIT(lock_hashtable_string); - return (java_objectheader *) js; + return (java_object_t *) js; } /* literalstring_new *********************************************************** - Creates a new javastring with the text of the utf-symbol and inserts it into - the string hashtable. + Creates a new literalstring with the text of the utf-symbol and inserts + it into the string hashtable. *******************************************************************************/ -java_objectheader *literalstring_new(utf *u) +java_object_t *literalstring_new(utf *u) { - char *utf_ptr; /* pointer to current unicode character */ + char *utf_ptr; /* pointer to current unicode character */ /* utf string */ - u4 utflength; /* length of utf-string if uncompressed */ - java_chararray *a; /* u2-array constructed from utf string */ - u4 i; + u4 utflength; /* length of utf-string if uncompressed */ + java_chararray_t *a; /* u2-array constructed from utf string */ + 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); + a = mem_alloc(sizeof(java_chararray_t) + sizeof(u2) * (utflength - 1) + 10); /* convert utf-string to u2-array */ for (i = 0; i < utflength; i++) @@ -657,23 +708,85 @@ java_objectheader *literalstring_new(utf *u) /* literalstring_free ********************************************************** - Removes a javastring from memory. + Removes a literalstring from memory. *******************************************************************************/ -void literalstring_free(java_objectheader* sobj) +#if 0 +/* TWISTI This one is currently not used. */ + +static void literalstring_free(java_object_t* string) { - java_lang_String *s; - java_chararray *a; + heapstring_t *s; + java_chararray_t *a; - s = (java_lang_String *) sobj; + s = (heapstring_t *) string; a = s->value; /* dispose memory of java.lang.String object */ - FREE(s, java_lang_String); + FREE(s, heapstring_t); /* dispose memory of java-characterarray */ - FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */ + FREE(a, sizeof(java_chararray_t) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */ +} +#endif + + +/* javastring_intern *********************************************************** + + Intern the given Java string. + + XXX NOTE: Literal Strings are direct references since they are not placed + onto the GC-Heap. That's why this function looks so "different". + +*******************************************************************************/ + +java_handle_t *javastring_intern(java_handle_t *s) +{ + java_lang_String *so; + java_chararray_t *value; + int32_t count; + int32_t offset; +/* java_lang_String *o; */ + java_object_t *o; /* XXX see note above */ + + so = (java_lang_String *) s; + + value = LLNI_field_direct(so, value); /* XXX see note above */ + LLNI_field_get_val(so, count, count); + LLNI_field_get_val(so, offset, offset); + + o = literalstring_u2(value, count, offset, true); + + return LLNI_WRAP(o); /* XXX see note above */ +} + + +/* javastring_fprint *********************************************************** + + Print the given Java string to the given stream. + +*******************************************************************************/ + +void javastring_fprint(java_handle_t *s, FILE *stream) +{ + java_lang_String *so; + java_handle_chararray_t *value; + int32_t count; + int32_t offset; + uint16_t c; + int i; + + so = (java_lang_String *) s; + + LLNI_field_get_ref(so, value, value); + LLNI_field_get_val(so, count, count); + LLNI_field_get_val(so, offset, offset); + + for (i = offset; i < offset + count; i++) { + c = LLNI_array_direct(value, i); + fputc(c, stream); + } } @@ -688,4 +801,5 @@ void literalstring_free(java_objectheader* sobj) * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */