1 /* native.c - table of native functions
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
31 The .hh files created with the header file generator are all
32 included here as are the C functions implementing these methods.
34 $Id: native.c 664 2003-11-21 18:24:01Z jowenn $
46 #include <sys/utsname.h>
51 #include "nativetypes.hh"
56 #include "toolbox/loging.h"
57 #include "threads/thread.h"
58 #include "threads/threadio.h"
59 #include "threads/locks.h"
61 /* Include files for IO functions */
65 #include <sys/types.h>
71 #include "../threads/threadio.h"
73 /* searchpath for classfiles */
74 static char *classpath;
76 /* for java-string to char conversion */
77 #define MAXSTRINGSIZE 1000
79 /******************** systemclasses required for native methods ***************/
81 static classinfo *class_java_lang_Class;
82 static classinfo *class_java_lang_VMClass;
83 static methodinfo *method_vmclass_init;
84 /* static classinfo *class_java_lang_Cloneable=0; */ /* now in global.h */
85 static classinfo *class_java_lang_CloneNotSupportedException;
86 static classinfo *class_java_lang_System;
87 static classinfo *class_java_lang_ClassLoader;
88 static classinfo *class_java_lang_ClassNotFoundException;
89 static classinfo *class_java_lang_InstantiationException;
90 static classinfo *class_java_lang_NoSuchMethodError;
91 static classinfo *class_java_lang_NoSuchFieldError;
92 static classinfo *class_java_lang_ClassFormatError;
93 static classinfo *class_java_lang_IllegalArgumentException;
94 static classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
95 static classinfo *class_java_lang_NoSuchFieldException;
96 static classinfo *class_java_io_SyncFailedException;
97 static classinfo *class_java_io_IOException;
98 static classinfo *class_java_io_FileNotFoundException;
99 static classinfo *class_java_io_UnixFileSystem;
100 static classinfo *class_java_security_PrivilegedActionException;
101 static classinfo *class_java_net_UnknownHostException;
102 static classinfo *class_java_net_SocketException;
103 static classinfo *class_java_lang_NoSuchMethodException;
104 static classinfo *class_java_lang_Double;
105 static classinfo *class_java_lang_Float;
106 static classinfo *class_java_lang_Long;
107 static classinfo *class_java_lang_Byte;
108 static classinfo *class_java_lang_Short;
109 static classinfo *class_java_lang_Boolean;
110 static classinfo *class_java_lang_Void;
111 static classinfo *class_java_lang_Character;
112 static classinfo *class_java_lang_Integer;
114 /* the system classloader object */
115 struct java_lang_ClassLoader *SystemClassLoader = NULL;
117 /* for raising exceptions from native methods */
118 java_objectheader* exceptionptr = NULL;
120 /************* use classinfo structure as java.lang.Class object **************/
122 void use_class_as_object(classinfo *c)
124 if (!class_java_lang_Class)
125 class_java_lang_Class =
126 class_new ( utf_new_char ("java/lang/Class") );
127 vftbl *vt = class_java_lang_Class->vftbl;
129 if (!c->classvftbl) {
130 c->classvftbl = true;
131 copy_vftbl(&newtbl, vt);
132 newtbl->class = c->header.vftbl->class;
133 newtbl->baseval = c->header.vftbl->baseval;
134 newtbl->diffval = c->header.vftbl->diffval;
135 c->header.vftbl = newtbl;
138 if (!class_java_lang_VMClass) {
139 class_java_lang_VMClass =
140 class_new ( utf_new_char("java/lang/VMClass"));
141 method_vmclass_init =
142 class_findmethod(class_java_lang_VMClass,utf_new_char("<init>"),
143 utf_new_char("(Lgnu/classpath/RawData;)V"));
144 if (method_vmclass_init==0) {
145 class_showmethods(class_java_lang_VMClass);
146 panic("Needed class initializer for VMClass could not be found");
150 java_objectheader *vmo = builtin_new (class_java_lang_VMClass);
151 asm_calljavamethod (method_vmclass_init, vmo, c, NULL, NULL);
152 c->vmClass=(java_lang_VMClass*)vmo;
156 /*********************** include Java Native Interface ************************/
160 /*************************** include native methods ***************************/
162 #include "nat/Runtime.c"
163 #include "nat/Thread.c"
164 #include "nat/VMClass.c"
165 #include "nat/Method.c"
166 #include "nat/VMSecurityManager.c"
167 #include "nat/VMClassLoader.c"
168 #include "nat/VMObject.c"
169 #include "nat/Proxy.c"
170 #include "nat/Field.c"
171 #include "nat/VMSystem.c"
172 #include "nat/Constructor.c"
173 #include "nat/FileChannelImpl.c"
174 #include "nat/VMObjectStreamClass.c"
175 #include "nat/JOWENNTest1.c"
178 #include "nat/GdkGraphics.c"
179 #include "nat/GtkComponentPeer.c"
180 #include "nat/GdkPixbufDecoder.c"
181 #include "nat/GtkScrollPanePeer.c"
182 #include "nat/GtkFileDialogPeer.c"
183 #include "nat/GtkLabelPeer.c"
185 /************************** tables for methods ********************************/
190 /* table for locating native methods */
191 static struct nativeref {
199 #include "nativetable.hh"
204 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
206 /* table for fast string comparison */
207 static struct nativecompref {
213 } nativecomptable [NATIVETABLESIZE];
215 /* string comparsion table initialized */
216 static bool nativecompdone = false;
219 /******************************************************************************/
220 /******************************************************************************/
221 #include "natcalls.h"
223 /* string call comparison table initialized */
225 /******************************************************************************/
226 /******************************************************************************/
228 /*--------------- native method calls & classes used -------------------------*/
233 /*********************** function: native_loadclasses **************************
235 load classes required for native methods
237 *******************************************************************************/
239 void native_loadclasses()
241 static int classesLoaded=0; /*temporary hack JoWenn*/
242 if (classesLoaded) return;
244 /* log_text("loadclasses entered");*/
247 /*class_java_lang_System =*/
248 (void)class_new ( utf_new_char ("java/lang/VMClass") );/*JoWenn*/
249 (void)class_new ( utf_new_char ("java/lang/Class") );/*JoWenn*/
250 /* class_new adds the class to the list of classes to be loaded */
251 if (!class_java_lang_Cloneable)
252 class_java_lang_Cloneable =
253 class_new ( utf_new_char ("java/lang/Cloneable") );
254 /* log_text("loadclasses: class_java_lang_Cloneable has been initialized");*/
255 class_java_lang_CloneNotSupportedException =
256 class_new ( utf_new_char ("java/lang/CloneNotSupportedException") );
257 if (!class_java_lang_Class)
258 class_java_lang_Class =
259 class_new ( utf_new_char ("java/lang/Class") );
260 class_java_io_IOException =
261 class_new(utf_new_char("java/io/IOException"));
262 class_java_io_FileNotFoundException =
263 class_new(utf_new_char("java/io/FileNotFoundException"));
264 class_java_lang_ClassNotFoundException =
265 class_new(utf_new_char("java/lang/ClassNotFoundException"));
266 class_java_lang_InstantiationException =
267 class_new(utf_new_char("java/lang/InstantiationException"));
268 class_java_lang_NoSuchMethodError =
269 class_new(utf_new_char("java/lang/NoSuchMethodError"));
270 class_java_lang_NoSuchFieldError =
271 class_new(utf_new_char("java/lang/NoSuchFieldError"));
272 class_java_lang_ClassFormatError =
273 class_new(utf_new_char("java/lang/ClassFormatError"));
274 class_java_io_SyncFailedException =
275 class_new ( utf_new_char ("java/io/SyncFailedException") );
277 /* log_text("native_loadclasses: class_new(\"java/lang/ClassLoader\")"); */
278 class_java_lang_ClassLoader =
279 class_new ( utf_new_char ("java/lang/ClassLoader") );
280 /* log_text("native_loadclasses: class_new(\"java/security/PrivilegedActionException\")"); */
281 class_java_security_PrivilegedActionException =
282 class_new(utf_new_char("java/security/PrivilegedActionException"));
284 class_java_net_UnknownHostException =
285 loader_load(utf_new_char("java/net/UnknownHostException"));
286 class_java_net_SocketException =
287 loader_load(utf_new_char("java/net/SocketException"));
289 class_java_lang_IllegalArgumentException =
290 class_new(utf_new_char("java/lang/IllegalArgumentException"));
291 class_java_lang_ArrayIndexOutOfBoundsException =
292 class_new(utf_new_char("java/lang/ArrayIndexOutOfBoundsException"));
293 class_java_lang_NoSuchFieldException =
294 class_new(utf_new_char("java/lang/NoSuchFieldException"));
295 class_java_lang_NoSuchMethodException =
296 class_new(utf_new_char("java/lang/NoSuchMethodException"));
298 /* load classes for wrapping primitive types */
299 class_java_lang_Double =
300 class_new( utf_new_char ("java/lang/Double") );
301 class_init(class_java_lang_Double);
303 class_java_lang_Float =
304 class_new(utf_new_char("java/lang/Float"));
305 class_java_lang_Character =
306 class_new(utf_new_char("java/lang/Character"));
307 class_java_lang_Integer =
308 class_new(utf_new_char("java/lang/Integer"));
309 class_java_lang_Long =
310 class_new(utf_new_char("java/lang/Long"));
311 class_java_lang_Byte =
312 class_new(utf_new_char("java/lang/Byte"));
313 class_java_lang_Short =
314 class_new(utf_new_char("java/lang/Short"));
315 class_java_lang_Boolean =
316 class_new(utf_new_char("java/lang/Boolean"));
317 class_java_lang_Void =
318 class_new(utf_new_char("java/lang/Void"));
320 /* load to avoid dynamic classloading */
321 /*JoWenn class_new(utf_new_char("sun/net/www/protocol/file/Handler"));
322 class_new(utf_new_char("sun/net/www/protocol/jar/Handler"));
323 class_new(utf_new_char("sun/io/CharToByteISO8859_1"));*/
325 /* start classloader */
326 /*JoWenn loader_load(utf_new_char("sun/io/ByteToCharISO8859_1")); */
329 log_text("native_loadclasses finished");
333 /*************** adds a class to the vector of loaded classes ****************/
335 void systemclassloader_addclass(classinfo *c)
339 /* find method addClass of java.lang.ClassLoader */
340 m = class_resolvemethod(
341 class_java_lang_ClassLoader,
342 utf_new_char("addClass"),
343 utf_new_char("(Ljava/lang/Class;)")
346 if (!m) panic("warning: cannot initialize classloader");
348 /* prepare class to be passed as argument */
349 use_class_as_object (c);
351 /* call 'addClass' */
352 asm_calljavamethod(m,
353 (java_objectheader*) SystemClassLoader,
354 (java_objectheader*) c,
360 /*************** adds a library to the vector of loaded libraries *************/
362 void systemclassloader_addlibrary(java_objectheader *o)
364 log_text("systemclassloader_addlibrary");
367 /*****************************************************************************
369 create systemclassloader object and initialize instance fields
371 ******************************************************************************/
373 void init_systemclassloader()
375 if (!SystemClassLoader) {
376 native_loadclasses();
377 log_text("Initializing new system class loader");
378 /* create object and call initializer */
379 SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader);
380 heap_addreference((void**) &SystemClassLoader);
382 /* systemclassloader has no parent */
383 SystemClassLoader->parent = NULL;
384 SystemClassLoader->initialized = true;
386 log_text("leaving system class loader");
390 /********************* add loaded library name *******************************/
392 void systemclassloader_addlibname(java_objectheader *o)
397 m = class_resolvemethod(loader_load(utf_new_char ("java/util/Vector")),
398 utf_new_char("addElement"),
399 utf_new_char("(Ljava/lang/Object;)V")
402 if (!m) panic("cannot initialize classloader");
404 id = envTable.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
405 if (!id) panic("can not access ClassLoader");
407 asm_calljavamethod(m,
408 GetStaticObjectField(&env,class_java_lang_ClassLoader,id),
416 /********************* function: native_setclasspath **************************/
418 void native_setclasspath (char *path)
420 /* set searchpath for classfiles */
424 /***************** function: throw_classnotfoundexception *********************/
426 void throw_classnotfoundexception()
428 if (!class_java_lang_ClassNotFoundException) {
429 panic("java.lang.ClassNotFoundException not found. Maybe wrong classpath?");
432 /* throws a ClassNotFoundException */
433 exceptionptr = native_new_and_init (class_java_lang_ClassNotFoundException);
437 void throw_classnotfoundexception2(utf* classname)
439 if (!class_java_lang_ClassNotFoundException) {
440 panic("java.lang.ClassNotFoundException not found. Maybe wrong classpath?");
443 /* throws a ClassNotFoundException */
444 exceptionptr = native_new_and_init (class_java_lang_ClassNotFoundException);
447 sprintf (logtext, "Loading class: ");
448 utf_sprint (logtext+strlen(logtext), classname);
450 log_text("Class not found");
455 /*********************** Function: native_findfunction *************************
457 Looks up a method (must have the same class name, method name, descriptor
458 and 'static'ness) and returns a function pointer to it.
459 Returns: function pointer or NULL (if there is no such method)
461 Remark: For faster operation, the names/descriptors are converted from C
462 strings to Unicode the first time this function is called.
464 *******************************************************************************/
466 functionptr native_findfunction(utf *cname, utf *mname,
467 utf *desc, bool isstatic)
470 /* entry of table for fast string comparison */
471 struct nativecompref *n;
472 /* for warning message if no function is found */
476 isstatic = isstatic ? true : false;
478 if (!nativecompdone) {
479 for (i = 0; i < NATIVETABLESIZE; i++) {
480 nativecomptable[i].classname =
481 utf_new_char(nativetable[i].classname);
482 nativecomptable[i].methodname =
483 utf_new_char(nativetable[i].methodname);
484 nativecomptable[i].descriptor =
485 utf_new_char(nativetable[i].descriptor);
486 nativecomptable[i].isstatic =
487 nativetable[i].isstatic;
488 nativecomptable[i].func =
491 nativecompdone = true;
496 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
498 buffer = MNEW(char, buffer_len);
500 strcpy(buffer, "searching matching function in native table:");
501 utf_sprint(buffer+strlen(buffer), mname);
502 strcpy(buffer+strlen(buffer), ": ");
503 utf_sprint(buffer+strlen(buffer), desc);
504 strcpy(buffer+strlen(buffer), " for class ");
505 utf_sprint(buffer+strlen(buffer), cname);
509 MFREE(buffer, char, buffer_len);
512 for (i = 0; i < NATIVETABLESIZE; i++) {
513 n = &(nativecomptable[i]);
515 if (cname == n->classname && mname == n->methodname &&
516 desc == n->descriptor && isstatic == n->isstatic)
520 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
524 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
526 buffer = MNEW(char, buffer_len);
528 strcpy(buffer, "comparing with:");
529 utf_sprint(buffer+strlen(buffer), n->methodname);
530 strcpy (buffer+strlen(buffer), ": ");
531 utf_sprint(buffer+strlen(buffer), n->descriptor);
532 strcpy(buffer+strlen(buffer), " for class ");
533 utf_sprint(buffer+strlen(buffer), n->classname);
537 MFREE(buffer, char, buffer_len);
545 /* no function was found, display warning */
548 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
550 buffer = MNEW(char, buffer_len);
552 strcpy(buffer, "warning: native function ");
553 utf_sprint(buffer + strlen(buffer), mname);
554 strcpy(buffer + strlen(buffer), ": ");
555 utf_sprint(buffer + strlen(buffer), desc);
556 strcpy(buffer + strlen(buffer), " not found in class ");
557 utf_sprint(buffer + strlen(buffer), cname);
561 MFREE(buffer, char, buffer_len);
571 /********************** function: javastring_new *******************************
573 creates a new object of type java/lang/String with the text of
574 the specified utf8-string
576 return: pointer to the string or NULL if memory is exhausted.
578 *******************************************************************************/
580 java_objectheader *javastring_new (utf *u)
582 char *utf_ptr = u->text; /* current utf character in utf string */
583 int utflength = utf_strlen(u); /* length of utf-string if uncompressed */
584 java_lang_String *s; /* result-string */
588 /* log_text("javastring_new");*/
590 s = (java_lang_String*) builtin_new (class_java_lang_String);
591 a = builtin_newarray_char (utflength);
593 /* javastring or character-array could not be created */
597 /* decompress utf-string */
598 for (i = 0; i < utflength; i++)
599 a->data[i] = utf_nextu2(&utf_ptr);
601 /* set fields of the javastring-object */
604 s->count = utflength;
606 return (java_objectheader*) s;
609 /********************** function: javastring_new_char **************************
611 creates a new java/lang/String object which contains the convertet
612 C-string passed via text.
614 return: the object pointer or NULL if memory is exhausted.
616 *******************************************************************************/
618 java_objectheader *javastring_new_char (char *text)
621 s4 len = strlen(text); /* length of the string */
622 java_lang_String *s; /* result-string */
625 /*log_text("javastring_new_char");*/
626 s = (java_lang_String*) builtin_new (class_java_lang_String);
627 a = builtin_newarray_char (len);
629 /* javastring or character-array could not be created */
630 if ((!a) || (!s)) return NULL;
633 for (i = 0; i < len; i++)
634 a->data[i] = text[i];
636 /* set fields of the javastring-object */
641 return (java_objectheader*) s;
645 /************************* function javastring_tochar **************************
647 converts a Java string into a C string.
649 return: pointer to C string
651 Caution: every call of this function overwrites the previous string !!!
653 *******************************************************************************/
655 static char stringbuffer[MAXSTRINGSIZE];
657 char *javastring_tochar (java_objectheader *so)
659 java_lang_String *s = (java_lang_String*) so;
663 log_text("javastring_tochar");
670 if (s->count > MAXSTRINGSIZE)
672 for (i = 0; i < s->count; i++)
673 stringbuffer[i] = a->data[s->offset+i];
674 stringbuffer[i] = '\0';
679 /****************** function class_findfield_approx ****************************
681 searches in 'classinfo'-structure for a field with the
684 *******************************************************************************/
686 fieldinfo *class_findfield_approx (classinfo *c, utf *name)
689 for (i = 0; i < c->fieldscount; i++) {
690 /* compare field names */
691 if ((c->fields[i].name == name))
692 return &(c->fields[i]);
695 /* field was not found, raise exception */
696 exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException);
701 /********************** function: native_new_and_init *************************
703 Creates a new object on the heap and calls the initializer.
704 Returns the object pointer or NULL if memory is exhausted.
706 *******************************************************************************/
708 java_objectheader *native_new_and_init(classinfo *c)
711 java_objectheader *o = builtin_new(c); /* create object */
714 printf("native_new_and_init ");
715 utf_display(c->name);
719 /* printf("o!=NULL\n"); */
720 /* find initializer */
722 m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
724 if (!m) { /* initializer not found */
726 sprintf(logtext, "Warning: class has no instance-initializer: ");
727 utf_sprint(logtext + strlen(logtext), c->name);
733 /* call initializer */
735 asm_calljavamethod(m, o, NULL, NULL, NULL);
740 /******************** function: stringtable_update ****************************
742 traverses the javastring hashtable and sets the vftbl-entries of
743 javastrings which were temporarily set to NULL, because
744 java.lang.Object was not yet loaded
746 *******************************************************************************/
748 void stringtable_update ()
750 java_lang_String *js;
752 literalstring *s; /* hashtable entry */
755 for (i = 0; i < string_hash.size; i++) {
756 s = string_hash.ptr[i];
760 js = (java_lang_String *) s->string;
762 if (!js || !(a = js->value))
763 /* error in hashtable found */
764 panic("invalid literalstring in hashtable");
766 if (!js->header.vftbl)
767 /* vftbl of javastring is NULL */
768 js->header.vftbl = class_java_lang_String -> vftbl;
770 if (!a->header.objheader.vftbl)
771 /* vftbl of character-array is NULL */
772 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
774 /* follow link in external hash chain */
782 /************************* function: u2_utflength ***************************
784 returns the utf length in bytes of a u2 array
786 *****************************************************************************/
789 u4 u2_utflength(u2 *text, u4 u2_length)
791 u4 result_len = 0; /* utf length in bytes */
792 u2 ch; /* current unicode character */
795 for (len = 0; len < u2_length; len++) {
797 /* next unicode character */
800 /* determine bytes required to store unicode character as utf */
801 if (ch && (ch < 0x80))
812 /********************* function: utf_new_u2 ***********************************
814 make utf symbol from u2 array,
815 if isclassname is true '.' is replaced by '/'
817 *******************************************************************************/
819 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
821 char *buffer; /* memory buffer for unicode characters */
822 char *pos; /* pointer to current position in buffer */
823 u4 left; /* unicode characters left */
824 u4 buflength; /* utf length in bytes of the u2 array */
825 utf *result; /* resulting utf-string */
828 /* determine utf length in bytes and allocate memory */
829 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
830 buflength = u2_utflength(unicode_pos, unicode_length);
831 buffer = MNEW(char,buflength);
833 /* memory allocation failed */
835 printf("length: %d\n",buflength);
836 log_text("utf_new_u2:buffer==NULL");
843 for (i = 0; i++ < unicode_length; unicode_pos++) {
844 /* next unicode character */
847 if ((c != 0) && (c < 0x80)) {
850 if ((int) left < 0) break;
851 /* convert classname */
852 if (isclassname && c=='.')
856 } else if (c < 0x800) {
858 unsigned char high = c >> 6;
859 unsigned char low = c & 0x3F;
861 if ((int) left < 0) break;
862 *pos++ = high | 0xC0;
867 char mid = (c >> 6) & 0x3F;
870 if ((int) left < 0) break;
871 *pos++ = high | 0xE0;
877 /* insert utf-string into symbol-table */
878 result = utf_new(buffer,buflength);
880 MFREE(buffer, char, buflength);
884 /********************* function: javastring_toutf *****************************
886 make utf symbol from javastring
888 *******************************************************************************/
890 utf *javastring_toutf(java_lang_String *string, bool isclassname)
892 java_lang_String *str = (java_lang_String *) string;
893 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count);
895 return utf_new_u2(str->value->data+str->offset,str->count, isclassname);
898 /********************* function: literalstring_u2 *****************************
900 searches for the javastring with the specified u2-array in
901 the string hashtable, if there is no such string a new one is
904 if copymode is true a copy of the u2-array is made
906 *******************************************************************************/
908 java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode )
910 literalstring *s; /* hashtable element */
911 java_lang_String *js; /* u2-array wrapped in javastring */
912 java_chararray *stringdata; /* copy of u2-array */
918 printf("literalstring_u2: length: %d\n",length);
919 log_text("literalstring_u2");
922 /* find location in hashtable */
923 key = unicode_hashkey (a->data, length);
924 slot = key & (string_hash.size-1);
925 s = string_hash.ptr[slot];
929 js = (java_lang_String *) s->string;
931 if (js->count == length) {
933 for (i=0; i<length; i++)
934 if (js->value->data[i] != a->data[i]) goto nomatch;
936 /* string already in hashtable, free memory */
938 lit_mem_free(a, sizeof(java_chararray) + sizeof(u2)*(length-1)+10);
941 log_text("literalstring_u2: foundentry");
942 utf_display(javastring_toutf(js,0));
944 return (java_objectheader *) js;
948 /* follow link in external hash chain */
953 /* create copy of u2-array for new javastring */
954 u4 arraysize = sizeof(java_chararray) + sizeof(u2)*(length-1)+10;
955 stringdata = lit_mem_alloc ( arraysize );
956 memcpy(stringdata, a, arraysize );
961 /* location in hashtable found, complete arrayheader */
962 stringdata -> header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
963 stringdata -> header.size = length;
965 /* create new javastring */
966 js = LNEW (java_lang_String);
967 js -> header.vftbl = class_java_lang_String -> vftbl;
968 js -> value = stringdata;
970 js -> count = length;
972 /* create new literalstring */
973 s = NEW (literalstring);
974 s->hashlink = string_hash.ptr[slot];
975 s->string = (java_objectheader *) js;
976 string_hash.ptr[slot] = s;
978 /* update numbe of hashtable entries */
979 string_hash.entries++;
981 /* reorganization of hashtable */
982 if ( string_hash.entries > (string_hash.size*2)) {
984 /* reorganization of hashtable, average length of
985 the external chains is approx. 2 */
989 hashtable newhash; /* the new hashtable */
991 /* create new hashtable, double the size */
992 init_hashtable(&newhash, string_hash.size*2);
993 newhash.entries=string_hash.entries;
995 /* transfer elements to new hashtable */
996 for (i=0; i<string_hash.size; i++) {
997 s = string_hash.ptr[i];
999 literalstring *nexts = s -> hashlink;
1000 js = (java_lang_String*) s->string;
1001 slot = (unicode_hashkey(js->value->data,js->count)) & (newhash.size-1);
1003 s->hashlink = newhash.ptr[slot];
1004 newhash.ptr[slot] = s;
1006 /* follow link in external hash chain */
1011 /* dispose old table */
1012 MFREE (string_hash.ptr, void*, string_hash.size);
1013 string_hash = newhash;
1015 #ifdef JOWENN_DEBUG1
1016 log_text("literalstring_u2: newly created");
1017 /* utf_display(javastring_toutf(js,0));*/
1020 return (java_objectheader *) js;
1023 /******************** Function: literalstring_new *****************************
1025 creates a new javastring with the text of the utf-symbol
1026 and inserts it into the string hashtable
1028 *******************************************************************************/
1030 java_objectheader *literalstring_new (utf *u)
1032 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1033 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1034 java_chararray *a; /* u2-array constructed from utf string */
1036 /* log_text("literalstring_new"); */
1037 /* utf_display(u);*/
1038 /*if (utflength==0) while (1) sleep(60);*/
1039 /* log_text("------------------"); */
1040 /* allocate memory */
1041 a = lit_mem_alloc (sizeof(java_chararray) + sizeof(u2)*(utflength-1)+10 );
1042 /* convert utf-string to u2-array */
1043 for (i=0; i<utflength; i++) a->data[i] = utf_nextu2(&utf_ptr);
1045 return literalstring_u2(a, utflength, false);
1049 /********************** function: literalstring_free **************************
1051 removes a javastring from memory
1053 ******************************************************************************/
1055 void literalstring_free (java_objectheader* sobj)
1057 java_lang_String *s = (java_lang_String*) sobj;
1058 java_chararray *a = s->value;
1060 log_text("literalstring_free called");
1062 /* dispose memory of java.lang.String object */
1063 LFREE (s, java_lang_String);
1064 /* dispose memory of java-characterarray */
1065 LFREE (a, sizeof(java_chararray) + sizeof(u2)*(a->header.size-1)); /* +10 ?? */
1071 void copy_vftbl(vftbl **dest, vftbl *src)
1075 /* XXX this kind of copying does not work (in the general
1076 * case). The interface tables would have to be copied, too. I
1077 * don't see why we should make a copy anyway. -Edwin
1079 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1080 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1081 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1085 /*****************************************************************************/
1086 /*****************************************************************************/
1089 /*--------------------------------------------------------*/
1090 void printNativeCall(nativeCall nc) {
1093 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1094 for (i=0; i<nc.methCnt; i++) {
1095 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1097 for (j=0; j<nc.callCnt[i]; j++) {
1098 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1099 nc.methods[i].methodCalls[j].classname,
1100 nc.methods[i].methodCalls[j].methodname,
1101 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1104 printf("-+++++--------------------\n");fflush(stdout);
1107 /*--------------------------------------------------------*/
1108 void printCompNativeCall(nativeCompCall nc) {
1110 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1111 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1112 utf_display(nc.classname); fflush(stdout);
1114 for (i=0; i<nc.methCnt; i++) {
1115 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1116 utf_display(nc.methods[i].methodname); fflush(stdout);
1117 utf_display(nc.methods[i].descriptor);fflush(stdout);
1118 printf("\n");fflush(stdout);
1120 for (j=0; j<nc.callCnt[i]; j++) {
1121 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1122 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1123 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1124 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1125 printf("\n");fflush(stdout);
1128 printf("---------------------\n");fflush(stdout);
1132 /*--------------------------------------------------------*/
1133 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1146 /*--------------------------------------------------------*/
1147 nativeCall* findNativeClassCalls(char *aclassname ) {
1150 for (i=0;i<NATIVECALLSSIZE; i++) {
1151 /* convert table to utf later to speed up search */
1152 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1153 return &nativeCalls[i];
1158 /*--------------------------------------------------------*/
1159 /*--------------------------------------------------------*/
1160 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1164 ncc->classname = utf_new_char(nc.classname);
1165 ncc->methCnt = nc.methCnt;
1167 for (i=0; i<nc.methCnt; i++) {
1168 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1169 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1170 ncc->callCnt[i] = nc.callCnt[i];
1172 for (j=0; j<nc.callCnt[i]; j++) {
1174 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1176 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1177 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1178 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1181 ncc->methods[i].methodCalls[j].methodname = NULL;
1182 ncc->methods[i].methodCalls[j].descriptor = NULL;
1190 /*--------------------------------------------------------*/
1192 bool natcall2utf(bool natcallcompdone) {
1195 if (natcallcompdone)
1198 for (i=0;i<NATIVECALLSSIZE; i++) {
1199 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1204 /*--------------------------------------------------------*/
1208 * These are local overrides for various environment variables in Emacs.
1209 * Please do not remove this and leave it at the end of the file, where
1210 * Emacs will automagically detect them.
1211 * ---------------------------------------------------------------------
1214 * indent-tabs-mode: t