1 /****************************** native.c ***************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Enth"alt die Tabellen f"ur die native-methods.
8 Die vom Headerfile-Generator erzeugten -.hh - Dateien werden hier
9 eingebunden, und ebenso alle C-Funktionen, mit denen diese
10 Methoden implementiert werden.
12 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
13 Roman Obermaisser EMAIL: cacao@complang.tuwien.ac.at
14 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
16 Last Change: 1996/11/14
18 *******************************************************************************/
24 #include "nativetypes.hh"
34 #include "threads/thread.h" /* schani */
35 #include "threads/locks.h"
37 /* INCLUDE-Files fuer IO-Funktionen */
41 #include <sys/types.h>
47 #include "../threads/threadio.h"
49 /* searchpath for classfiles */
50 static char *classpath;
52 /* for java-string to char conversion */
53 #define MAXSTRINGSIZE 1000
55 /******************** systemclasses required for native methods ***************/
57 static classinfo *class_java_lang_Class;
58 static classinfo *class_java_lang_Cloneable;
59 static classinfo *class_java_lang_CloneNotSupportedException;
60 static classinfo *class_java_lang_System;
61 static classinfo *class_java_lang_ClassLoader;
62 static classinfo *class_java_lang_ClassNotFoundException;
63 static classinfo *class_java_lang_InstantiationException;
64 static classinfo *class_java_lang_NoSuchMethodError;
65 static classinfo *class_java_lang_NoSuchFieldError;
66 static classinfo *class_java_lang_ClassFormatError;
67 static classinfo *class_java_lang_IllegalArgumentException;
68 static classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
69 static classinfo *class_java_lang_NoSuchFieldException;
70 static classinfo *class_java_io_SyncFailedException;
71 static classinfo *class_java_io_IOException;
72 static classinfo *class_java_io_UnixFileSystem;
73 static classinfo *class_java_security_PrivilegedActionException;
74 static classinfo *class_java_net_UnknownHostException;
75 static classinfo *class_java_net_SocketException;
76 static classinfo *class_java_lang_NoSuchMethodException;
77 static classinfo *class_java_lang_Double;
78 static classinfo *class_java_lang_Float;
79 static classinfo *class_java_lang_Long;
80 static classinfo *class_java_lang_Byte;
81 static classinfo *class_java_lang_Short;
82 static classinfo *class_java_lang_Boolean;
83 static classinfo *class_java_lang_Void;
84 static classinfo *class_java_lang_Character;
85 static classinfo *class_java_lang_Integer;
87 /* the system classloader object */
88 struct java_lang_ClassLoader *SystemClassLoader = NULL;
90 /* for raising exceptions from native methods */
91 java_objectheader* exceptionptr = NULL;
93 /************* use classinfo structure as java.lang.Class object **************/
95 static void use_class_as_object (classinfo *c)
97 c->header.vftbl = class_java_lang_Class -> vftbl;
100 /*********************** include Java Native Interface ************************/
104 /*************************** include native methods ***************************/
106 #include "nat/Object.c"
107 #include "nat/String.c"
108 #include "nat/ClassLoader.c"
109 #include "nat/Class.c"
110 #include "nat/Compiler.c"
111 #include "nat/Double.c"
112 #include "nat/Float.c"
113 #include "nat/Math.c"
114 #include "nat/Package.c"
115 #include "nat/Runtime.c"
116 #include "nat/SecurityManager.c"
117 #include "nat/System.c"
118 #include "nat/Thread.c"
119 #include "nat/Throwable.c"
120 #include "nat/Finalizer.c"
121 #include "nat/Array.c"
122 #include "nat/Constructor.c"
123 #include "nat/Field.c"
124 #include "nat/Method.c"
125 #include "nat/FileDescriptor.c"
126 #include "nat/FileInputStream.c"
127 #include "nat/FileOutputStream.c"
128 #include "nat/FileSystem.c"
129 #include "nat/ObjectInputStream.c"
130 #include "nat/ObjectStreamClass.c"
131 #include "nat/RandomAccessFile.c"
132 #include "nat/ResourceBundle.c"
133 #include "nat/JarFile.c"
134 #include "nat/Adler32.c"
135 #include "nat/CRC32.c"
136 #include "nat/Deflater.c"
137 #include "nat/Inflater.c"
138 #include "nat/ZipEntry.c"
139 #include "nat/ZipFile.c"
140 #include "nat/BigInteger.c"
141 #include "nat/InetAddress.c"
142 #include "nat/InetAddressImpl.c"
143 #include "nat/DatagramPacket.c"
144 #include "nat/PlainDatagramSocketImpl.c"
145 #include "nat/PlainSocketImpl.c"
146 #include "nat/SocketInputStream.c"
147 #include "nat/SocketOutputStream.c"
148 #include "nat/AccessController.c"
149 #include "nat/ClassLoader_NativeLibrary.c"
150 #include "nat/UnixFileSystem.c"
152 /************************** tables for methods ********************************/
154 /* table for locating native methods */
155 static struct nativeref {
163 #include "nativetable.hh"
168 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
170 /* table for fast string comparison */
171 static struct nativecompref {
177 } nativecomptable [NATIVETABLESIZE];
179 /* string comparsion table initialized */
180 static bool nativecompdone = false;
183 /*********************** function: native_loadclasses **************************
185 load classes required for native methods
187 *******************************************************************************/
189 void native_loadclasses()
191 /* class_new adds the class to the list of classes to be loaded */
192 class_java_lang_Cloneable =
193 class_new ( utf_new_char ("java/lang/Cloneable") );
194 class_java_lang_CloneNotSupportedException =
195 class_new ( utf_new_char ("java/lang/CloneNotSupportedException") );
196 class_java_lang_Class =
197 class_new ( utf_new_char ("java/lang/Class") );
198 class_java_io_IOException =
199 class_new ( utf_new_char ("java/io/IOException") );
200 class_java_lang_ClassNotFoundException =
201 class_new ( utf_new_char ("java/lang/ClassNotFoundException") );
202 class_java_lang_InstantiationException =
203 class_new ( utf_new_char ("java/lang/InstantiationException") );
204 class_java_lang_NoSuchMethodError =
205 class_new ( utf_new_char ("java/lang/NoSuchMethodError") );
206 class_java_lang_NoSuchFieldError =
207 class_new ( utf_new_char ("java/lang/NoSuchFieldError") );
208 class_java_lang_ClassFormatError =
209 class_new ( utf_new_char ("java/lang/ClassFormatError") );
210 class_java_io_SyncFailedException =
211 class_new ( utf_new_char ("java/io/SyncFailedException") );
212 class_java_io_UnixFileSystem =
213 class_new ( utf_new_char ("java/io/UnixFileSystem") );
214 class_java_lang_System =
215 class_new ( utf_new_char ("java/lang/System") );
216 class_java_lang_ClassLoader =
217 class_new ( utf_new_char ("java/lang/ClassLoader") );
218 class_java_security_PrivilegedActionException =
219 class_new( utf_new_char("java/security/PrivilegedActionException"));
220 class_java_net_UnknownHostException =
221 loader_load( utf_new_char ("java/net/UnknownHostException") );
222 class_java_net_SocketException =
223 loader_load( utf_new_char ("java/net/SocketException") );
224 class_java_lang_IllegalArgumentException =
225 class_new( utf_new_char("java/lang/IllegalArgumentException"));
226 class_java_lang_ArrayIndexOutOfBoundsException =
227 class_new( utf_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
228 class_java_lang_NoSuchFieldException =
229 class_new( utf_new_char ("java/lang/NoSuchFieldException") );
230 class_java_lang_NoSuchMethodException =
231 class_new( utf_new_char ("java/lang/NoSuchMethodException") );
233 /* load classes for wrapping primitive types */
234 class_java_lang_Double =
235 class_new( utf_new_char ("java/lang/Double") );
236 class_java_lang_Float =
237 class_new( utf_new_char ("java/lang/Float") );
238 class_java_lang_Character =
239 class_new( utf_new_char ("java/lang/Character") );
240 class_java_lang_Integer =
241 class_new( utf_new_char ("java/lang/Integer") );
242 class_java_lang_Long =
243 class_new( utf_new_char ("java/lang/Long") );
244 class_java_lang_Byte =
245 class_new( utf_new_char ("java/lang/Byte") );
246 class_java_lang_Short =
247 class_new( utf_new_char ("java/lang/Short") );
248 class_java_lang_Boolean =
249 class_new( utf_new_char ("java/lang/Boolean") );
250 class_java_lang_Void =
251 class_new( utf_new_char ("java/lang/Void") );
253 /* load to avoid dynamic classloading */
254 class_new(utf_new_char("sun/net/www/protocol/file/Handler"));
255 class_new(utf_new_char("sun/net/www/protocol/jar/Handler"));
256 class_new(utf_new_char("sun/io/CharToByteISO8859_1"));
258 /* start classloader */
259 loader_load(utf_new_char("sun/io/ByteToCharISO8859_1"));
263 /*************** adds a class to the vector of loaded classes ****************/
265 void systemclassloader_addclass(classinfo *c)
269 /* find method addClass of java.lang.ClassLoader */
270 m = class_resolvemethod (
271 class_java_lang_ClassLoader,
272 utf_new_char("addClass"),
273 utf_new_char("(Ljava/lang/Class;)")
276 if (!m) panic("warning: cannot initialize classloader");
278 /* prepare class to be passed as argument */
279 use_class_as_object (c);
281 /* call 'addClass' */
282 asm_calljavamethod(m,
283 (java_objectheader*) SystemClassLoader,
284 (java_objectheader*) c,
290 /*************** adds a library to the vector of loaded libraries *************/
292 void systemclassloader_addlibrary(java_objectheader *o)
296 /* find method addElement of java.util.Vector */
297 m = class_resolvemethod (
298 loader_load ( utf_new_char ("java/util/Vector") ),
299 utf_new_char("addElement"),
300 utf_new_char("(Ljava/lang/Object;)V")
303 if (!m) panic("cannot initialize classloader");
305 /* call 'addElement' */
306 asm_calljavamethod(m,
307 SystemClassLoader->nativeLibraries,
314 /*****************************************************************************
316 create systemclassloader object and initialize instance fields
318 ******************************************************************************/
320 void init_systemclassloader()
322 if (!SystemClassLoader) {
324 /* create object and call initializer */
325 SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader);
326 heap_addreference((void**) &SystemClassLoader);
328 /* systemclassloader has no parent */
329 SystemClassLoader->parent = NULL;
330 SystemClassLoader->initialized = true;
335 /********************* add loaded library name *******************************/
337 void systemclassloader_addlibname(java_objectheader *o)
340 java_objectheader *LibraryNameVector;
343 m = class_resolvemethod (
344 loader_load ( utf_new_char ("java/util/Vector") ),
345 utf_new_char("addElement"),
346 utf_new_char("(Ljava/lang/Object;)V")
349 if (!m) panic("cannot initialize classloader");
351 id = env.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
352 if (!id) panic("can not access ClassLoader");
354 asm_calljavamethod(m,
355 GetStaticObjectField(&env,class_java_lang_ClassLoader,id),
363 /********************* function: native_setclasspath **************************/
365 void native_setclasspath (char *path)
367 /* set searchpath for classfiles */
371 /***************** function: throw_classnotfoundexception *********************/
373 void throw_classnotfoundexception()
375 /* throws a ClassNotFoundException */
376 exceptionptr = native_new_and_init (class_java_lang_ClassNotFoundException);
380 /*********************** Funktion: native_findfunction *************************
382 Sucht in der Tabelle die passende Methode (muss mit Klassennamen,
383 Methodennamen, Descriptor und 'static'-Status "ubereinstimmen),
384 und gibt den Funktionszeiger darauf zur"uck.
385 Return: Funktionszeiger oder NULL (wenn es keine solche Methode gibt)
387 Anmerkung: Zu Beschleunigung des Suchens werden die als C-Strings
388 vorliegenden Namen/Descriptors in entsprechende unicode-Symbole
389 umgewandelt (beim ersten Aufruf dieser Funktion).
391 *******************************************************************************/
393 functionptr native_findfunction (utf *cname, utf *mname,
394 utf *desc, bool isstatic)
397 /* entry of table for fast string comparison */
398 struct nativecompref *n;
399 /* for warning message if no function is found */
403 isstatic = isstatic ? true : false;
405 if (!nativecompdone) {
406 for (i = 0; i < NATIVETABLESIZE; i++) {
407 nativecomptable[i].classname =
408 utf_new_char(nativetable[i].classname);
409 nativecomptable[i].methodname =
410 utf_new_char(nativetable[i].methodname);
411 nativecomptable[i].descriptor =
412 utf_new_char(nativetable[i].descriptor);
413 nativecomptable[i].isstatic =
414 nativetable[i].isstatic;
415 nativecomptable[i].func =
418 nativecompdone = true;
421 for (i = 0; i < NATIVETABLESIZE; i++) {
422 n = &(nativecomptable[i]);
424 if (cname == n->classname && mname == n->methodname &&
425 desc == n->descriptor && isstatic == n->isstatic)
429 /* no function was found, display warning */
432 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
434 buffer = MNEW(char, buffer_len);
436 strcpy(buffer, "warning: native function ");
437 utf_sprint(buffer+strlen(buffer), mname);
438 strcpy(buffer+strlen(buffer), ": ");
439 utf_sprint(buffer+strlen(buffer), desc);
440 strcpy(buffer+strlen(buffer), " not found in class ");
441 utf_sprint(buffer+strlen(buffer), cname);
445 MFREE(buffer, char, buffer_len);
451 /********************** function: javastring_new *******************************
453 creates a new object of type java/lang/String with the text of
454 the specified utf8-string
456 return: pointer to the string or NULL if memory is exhausted.
458 *******************************************************************************/
460 java_objectheader *javastring_new (utf *u)
462 char *utf_ptr = u->text; /* current utf character in utf string */
463 int utflength = utf_strlen(u); /* length of utf-string if uncompressed */
464 java_lang_String *s; /* result-string */
468 s = (java_lang_String*) builtin_new (class_java_lang_String);
469 a = builtin_newarray_char (utflength);
471 /* javastring or character-array could not be created */
475 /* decompress utf-string */
476 for (i = 0; i < utflength; i++)
477 a->data[i] = utf_nextu2(&utf_ptr);
479 /* set fields of the javastring-object */
482 s -> count = utflength;
484 return (java_objectheader*) s;
487 /********************** function: javastring_new_char **************************
489 creates a new java/lang/String object which contains the convertet
490 C-string passed via text.
492 return: the object pointer or NULL if memory is exhausted.
494 *******************************************************************************/
496 java_objectheader *javastring_new_char (char *text)
499 s4 len = strlen(text); /* length of the string */
500 java_lang_String *s; /* result-string */
503 s = (java_lang_String*) builtin_new (class_java_lang_String);
504 a = builtin_newarray_char (len);
506 /* javastring or character-array could not be created */
507 if ((!a) || (!s)) return NULL;
510 for (i = 0; i < len; i++)
511 a->data[i] = text[i];
513 /* set fields of the javastring-object */
518 return (java_objectheader*) s;
522 /************************* function javastring_tochar **************************
524 converts a Java string into a C string.
526 return: pointer to C string
528 Caution: every call of this function overwrites the previous string !!!
530 *******************************************************************************/
532 static char stringbuffer[MAXSTRINGSIZE];
534 char *javastring_tochar (java_objectheader *so)
536 java_lang_String *s = (java_lang_String*) so;
545 if (s->count > MAXSTRINGSIZE)
547 for (i = 0; i < s->count; i++)
548 stringbuffer[i] = a->data[s->offset+i];
549 stringbuffer[i] = '\0';
554 /****************** function class_findfield_approx ****************************
556 searches in 'classinfo'-structure for a field with the
559 *******************************************************************************/
561 fieldinfo *class_findfield_approx (classinfo *c, utf *name)
564 for (i = 0; i < c->fieldscount; i++) {
565 /* compare field names */
566 if ((c->fields[i].name == name))
567 return &(c->fields[i]);
570 /* field was not found, raise exception */
571 exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException);
576 /********************** function: native_new_and_init *************************
578 Creates a new object on the heap and calls the initializer.
579 Returns the object pointer or NULL if memory is exhausted.
581 *******************************************************************************/
583 java_objectheader *native_new_and_init (classinfo *c)
586 java_objectheader *o = builtin_new (c); /* create object */
590 /* find initializer */
592 m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
594 if (!m) { /* initializer not found */
596 sprintf(logtext, "Warning: class has no instance-initializer: ");
597 utf_sprint(logtext + strlen(logtext), c->name);
603 /* call initializer */
605 asm_calljavamethod (m, o, NULL, NULL, NULL);
609 /******************** function: stringtable_update ****************************
611 traverses the javastring hashtable and sets the vftbl-entries of
612 javastrings which were temporarily set to NULL, because
613 java.lang.Object was not yet loaded
615 *******************************************************************************/
617 void stringtable_update ()
619 java_lang_String *js;
621 literalstring *s; /* hashtable entry */
624 for (i = 0; i < string_hash.size; i++) {
625 s = string_hash.ptr[i];
629 js = (java_lang_String *) s->string;
631 if (!js || !(a = js->value))
632 /* error in hashtable found */
633 panic("invalid literalstring in hashtable");
635 if (!js->header.vftbl)
636 /* vftbl of javastring is NULL */
637 js->header.vftbl = class_java_lang_String -> vftbl;
639 if (!a->header.objheader.vftbl)
640 /* vftbl of character-array is NULL */
641 a->header.objheader.vftbl = class_array -> vftbl;
643 /* follow link in external hash chain */
651 /************************* function: u2_utflength ***************************
653 returns the utf length in bytes of a u2 array
655 *****************************************************************************/
658 u4 u2_utflength(u2 *text, u4 u2_length)
660 u4 result_len = 0; /* utf length in bytes */
661 u2 ch; /* current unicode character */
664 for (len = 0; len < u2_length; len++) {
666 /* next unicode character */
669 /* determine bytes required to store unicode character as utf */
670 if (ch && (ch < 0x80))
681 /********************* function: utf_new_u2 ***********************************
683 make utf symbol from u2 array,
684 if isclassname is true '.' is replaced by '/'
686 *******************************************************************************/
688 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
690 char *buffer; /* memory buffer for unicode characters */
691 char *pos; /* pointer to current position in buffer */
692 u4 left; /* unicode characters left */
693 u4 buflength; /* utf length in bytes of the u2 array */
694 utf *result; /* resulting utf-string */
697 /* determine utf length in bytes and allocate memory */
698 buflength = u2_utflength(unicode_pos, unicode_length);
699 buffer = MNEW(char,buflength);
701 /* memory allocation failed */
702 if (!buffer) return NULL;
707 for (i = 0; i++ < unicode_length; unicode_pos++) {
708 /* next unicode character */
711 if ((c != 0) && (c < 0x80)) {
714 if ((int) left < 0) break;
715 /* convert classname */
716 if (isclassname && c=='.')
720 } else if (c < 0x800) {
722 unsigned char high = c >> 6;
723 unsigned char low = c & 0x3F;
725 if ((int) left < 0) break;
726 *pos++ = high | 0xC0;
731 char mid = (c >> 6) & 0x3F;
734 if ((int) left < 0) break;
735 *pos++ = high | 0xE0;
741 /* insert utf-string into symbol-table */
742 result = utf_new(buffer,buflength);
743 MFREE(buffer, char, buflength);
747 /********************* function: javastring_toutf *****************************
749 make utf symbol from javastring
751 *******************************************************************************/
753 utf *javastring_toutf(java_lang_String *string, bool isclassname)
755 java_lang_String *str = (java_lang_String *) string;
756 return utf_new_u2(str->value->data,str->count, isclassname);
759 /********************* function: literalstring_u2 *****************************
761 searches for the javastring with the specified u2-array in
762 the string hashtable, if there is no such string a new one is
765 if copymode is true a copy of the u2-array is made
767 *******************************************************************************/
769 java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode )
771 literalstring *s; /* hashtable element */
772 java_lang_String *js; /* u2-array wrapped in javastring */
773 java_chararray *stringdata; /* copy of u2-array */
778 /* find location in hashtable */
779 key = unicode_hashkey (a->data, length);
780 slot = key & (string_hash.size-1);
781 s = string_hash.ptr[slot];
785 js = (java_lang_String *) s->string;
787 if (js->count == length) {
789 for (i=0; i<length; i++)
790 if (js->value->data[i] != a->data[i]) goto nomatch;
792 /* string already in hashtable, free memory */
794 lit_mem_free(a, sizeof(java_chararray) + sizeof(u2)*(length-1)+10);
796 return (java_objectheader *) js;
800 /* follow link in external hash chain */
805 /* create copy of u2-array for new javastring */
806 u4 arraysize = sizeof(java_chararray) + sizeof(u2)*(length-1)+10;
807 stringdata = lit_mem_alloc ( arraysize );
808 memcpy(stringdata, a, arraysize );
813 /* location in hashtable found, complete arrayheader */
814 if (class_array==NULL) panic("class_array not initialized");
815 stringdata -> header.objheader.vftbl = class_array -> vftbl;
816 stringdata -> header.size = length;
817 stringdata -> header.arraytype = ARRAYTYPE_CHAR;
819 /* create new javastring */
820 js = LNEW (java_lang_String);
821 js -> header.vftbl = class_java_lang_String -> vftbl;
822 js -> value = stringdata;
824 js -> count = length;
826 /* create new literalstring */
827 s = NEW (literalstring);
828 s->hashlink = string_hash.ptr[slot];
829 s->string = (java_objectheader *) js;
830 string_hash.ptr[slot] = s;
832 /* update numbe of hashtable entries */
833 string_hash.entries++;
835 /* reorganization of hashtable */
836 if ( string_hash.entries > (string_hash.size*2)) {
838 /* reorganization of hashtable, average length of
839 the external chains is approx. 2 */
843 hashtable newhash; /* the new hashtable */
845 /* create new hashtable, double the size */
846 init_hashtable(&newhash, string_hash.size*2);
847 newhash.entries=string_hash.entries;
849 /* transfer elements to new hashtable */
850 for (i=0; i<string_hash.size; i++) {
851 s = string_hash.ptr[i];
853 literalstring *nexts = s -> hashlink;
854 js = (java_lang_String*) s->string;
855 slot = (unicode_hashkey(js->value->data,js->count)) & (newhash.size-1);
857 s->hashlink = newhash.ptr[slot];
858 newhash.ptr[slot] = s;
860 /* follow link in external hash chain */
865 /* dispose old table */
866 MFREE (string_hash.ptr, void*, string_hash.size);
867 string_hash = newhash;
870 return (java_objectheader *) js;
873 /******************** Funktion: literalstring_new *****************************
875 creates a new javastring with the text of the utf-symbol
876 and inserts it into the string hashtable
878 *******************************************************************************/
880 java_objectheader *literalstring_new (utf *u)
882 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
883 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
884 java_chararray *a; /* u2-array constructed from utf string */
885 java_objectheader *js;
888 /* allocate memory */
889 a = lit_mem_alloc (sizeof(java_chararray) + sizeof(u2)*(utflength-1)+10 );
890 /* convert utf-string to u2-array */
891 for (i=0; i<utflength; i++) a->data[i] = utf_nextu2(&utf_ptr);
893 return literalstring_u2(a, utflength, false);
897 /********************** function: literalstring_free **************************
899 removes a javastring from memory
901 ******************************************************************************/
903 void literalstring_free (java_objectheader* sobj)
905 java_lang_String *s = (java_lang_String*) sobj;
906 java_chararray *a = s->value;
908 log_text("literalstring_free called");
910 /* dispose memory of java.lang.String object */
911 LFREE (s, java_lang_String);
912 /* dispose memory of java-characterarray */
913 LFREE (a, sizeof(java_chararray) + sizeof(u2)*(a->header.size-1)); /* +10 ?? */