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 682 2003-12-01 15:33:30Z jowenn $
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 */
76 /* for java-string to char conversion */
77 #define MAXSTRINGSIZE 1000
79 /******************** systemclasses required for native methods ***************/
81 classinfo *class_java_lang_Class;
82 classinfo *class_java_lang_VMClass;
83 methodinfo *method_vmclass_init;
84 /* static classinfo *class_java_lang_Cloneable=0; */ /* now in global.h */
85 classinfo *class_java_lang_CloneNotSupportedException;
86 classinfo *class_java_lang_System;
87 classinfo *class_java_lang_ClassLoader;
88 classinfo *class_java_lang_ClassNotFoundException;
89 classinfo *class_java_lang_LinkageError;
90 classinfo *class_java_lang_InstantiationException;
91 classinfo *class_java_lang_NoSuchMethodError;
92 classinfo *class_java_lang_NoSuchFieldError;
93 classinfo *class_java_lang_ClassFormatError;
94 classinfo *class_java_lang_IllegalArgumentException;
95 classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
96 classinfo *class_java_lang_NoSuchFieldException;
97 classinfo *class_java_io_SyncFailedException;
98 classinfo *class_java_io_IOException;
99 classinfo *class_java_io_FileNotFoundException;
100 classinfo *class_java_io_UnixFileSystem;
101 classinfo *class_java_security_PrivilegedActionException;
102 classinfo *class_java_net_UnknownHostException;
103 classinfo *class_java_net_SocketException;
104 classinfo *class_java_lang_NoSuchMethodException;
105 classinfo *class_java_lang_Double;
106 classinfo *class_java_lang_Float;
107 classinfo *class_java_lang_Long;
108 classinfo *class_java_lang_Byte;
109 classinfo *class_java_lang_Short;
110 classinfo *class_java_lang_Boolean;
111 classinfo *class_java_lang_Void;
112 classinfo *class_java_lang_Character;
113 classinfo *class_java_lang_Integer;
115 /* the system classloader object */
116 struct java_lang_ClassLoader *SystemClassLoader = NULL;
118 /* for raising exceptions from native methods */
119 java_objectheader* exceptionptr = NULL;
121 /************* use classinfo structure as java.lang.Class object **************/
123 void use_class_as_object(classinfo *c)
125 /*log_text("use_class_as_object");*/
126 if (!class_java_lang_Class)
127 class_java_lang_Class =
128 class_new ( utf_new_char ("java/lang/Class") );
129 vftbl *vt = class_java_lang_Class->vftbl;
131 if (!c->classvftbl) {
132 c->classvftbl = true;
134 /* copy_vftbl(&newtbl, vt);
135 newtbl->class = c->header.vftbl->class;
136 newtbl->baseval = c->header.vftbl->baseval;
137 newtbl->diffval = c->header.vftbl->diffval;
138 c->header.vftbl = newtbl;*/
140 c->header.vftbl=class_java_lang_Class->vftbl;
142 if (!class_java_lang_VMClass) {
143 class_java_lang_VMClass =
144 loader_load ( utf_new_char("java/lang/VMClass"));
145 method_vmclass_init =
146 class_findmethod(class_java_lang_VMClass,utf_new_char("<init>"),
147 utf_new_char("(Lgnu/classpath/RawData;)V"));
148 if (method_vmclass_init==0) {
149 class_showmethods(class_java_lang_VMClass);
150 panic("Needed class initializer for VMClass could not be found");
154 java_objectheader *vmo = builtin_new (class_java_lang_VMClass);
156 if (!vmo) panic("Error while creating instance of java/lang/VMClass");
157 asm_calljavamethod (method_vmclass_init, vmo, c, NULL, NULL);
158 c->vmClass=(java_lang_VMClass*)vmo;
159 /*log_text("VMCLASS has been attached");*/
166 /*************************** include native methods ***************************/
169 #include "nat/GdkGraphics.c"
170 #include "nat/GtkComponentPeer.c"
171 #include "nat/GdkPixbufDecoder.c"
172 #include "nat/GtkScrollPanePeer.c"
173 #include "nat/GtkFileDialogPeer.c"
174 #include "nat/GtkLabelPeer.c"
178 /************************** tables for methods ********************************/
183 /* table for locating native methods */
184 static struct nativeref {
192 #include "nativetable.hh"
197 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
199 /* table for fast string comparison */
200 static struct nativecompref {
206 } nativecomptable [NATIVETABLESIZE];
208 /* string comparsion table initialized */
209 static bool nativecompdone = false;
212 /******************************************************************************/
213 /******************************************************************************/
214 #include "natcalls.h"
216 /* string call comparison table initialized */
218 /******************************************************************************/
219 /******************************************************************************/
221 /*--------------- native method calls & classes used -------------------------*/
226 /*********************** function: native_loadclasses **************************
228 load classes required for native methods
230 *******************************************************************************/
232 void native_loadclasses()
234 static int classesLoaded=0; /*temporary hack JoWenn*/
235 if (classesLoaded) return;
237 /* log_text("loadclasses entered");*/
240 /*class_java_lang_System =*/
241 (void)class_new ( utf_new_char ("java/lang/VMClass") );/*JoWenn*/
242 (void)class_new ( utf_new_char ("java/lang/Class") );/*JoWenn*/
243 /* class_new adds the class to the list of classes to be loaded */
244 if (!class_java_lang_Cloneable)
245 class_java_lang_Cloneable =
246 class_new ( utf_new_char ("java/lang/Cloneable") );
247 /* log_text("loadclasses: class_java_lang_Cloneable has been initialized");*/
248 class_java_lang_CloneNotSupportedException =
249 class_new ( utf_new_char ("java/lang/CloneNotSupportedException") );
250 if (!class_java_lang_Class)
251 class_java_lang_Class =
252 class_new ( utf_new_char ("java/lang/Class") );
253 class_java_io_IOException =
254 class_new(utf_new_char("java/io/IOException"));
255 class_java_io_FileNotFoundException =
256 class_new(utf_new_char("java/io/FileNotFoundException"));
257 class_java_lang_ClassNotFoundException =
258 class_new(utf_new_char("java/lang/ClassNotFoundException"));
259 class_java_lang_LinkageError =
260 class_new(utf_new_char("java/lang/LinkageError"));
261 class_java_lang_InstantiationException =
262 class_new(utf_new_char("java/lang/InstantiationException"));
263 class_java_lang_NoSuchMethodError =
264 class_new(utf_new_char("java/lang/NoSuchMethodError"));
265 class_java_lang_NoSuchFieldError =
266 class_new(utf_new_char("java/lang/NoSuchFieldError"));
267 class_java_lang_ClassFormatError =
268 class_new(utf_new_char("java/lang/ClassFormatError"));
269 class_java_io_SyncFailedException =
270 class_new ( utf_new_char ("java/io/SyncFailedException") );
272 /* log_text("native_loadclasses: class_new(\"java/lang/ClassLoader\")"); */
273 class_java_lang_ClassLoader =
274 class_new ( utf_new_char ("java/lang/ClassLoader") );
275 /* log_text("native_loadclasses: class_new(\"java/security/PrivilegedActionException\")"); */
276 class_java_security_PrivilegedActionException =
277 class_new(utf_new_char("java/security/PrivilegedActionException"));
279 class_java_net_UnknownHostException =
280 loader_load(utf_new_char("java/net/UnknownHostException"));
281 class_java_net_SocketException =
282 loader_load(utf_new_char("java/net/SocketException"));
284 class_java_lang_IllegalArgumentException =
285 class_new(utf_new_char("java/lang/IllegalArgumentException"));
286 class_java_lang_ArrayIndexOutOfBoundsException =
287 class_new(utf_new_char("java/lang/ArrayIndexOutOfBoundsException"));
288 class_java_lang_NoSuchFieldException =
289 class_new(utf_new_char("java/lang/NoSuchFieldException"));
290 class_java_lang_NoSuchMethodException =
291 class_new(utf_new_char("java/lang/NoSuchMethodException"));
293 /* load classes for wrapping primitive types */
294 class_java_lang_Double =
295 class_new( utf_new_char ("java/lang/Double") );
296 class_init(class_java_lang_Double);
298 class_java_lang_Float =
299 class_new(utf_new_char("java/lang/Float"));
300 class_java_lang_Character =
301 class_new(utf_new_char("java/lang/Character"));
302 class_java_lang_Integer =
303 class_new(utf_new_char("java/lang/Integer"));
304 class_java_lang_Long =
305 class_new(utf_new_char("java/lang/Long"));
306 class_java_lang_Byte =
307 class_new(utf_new_char("java/lang/Byte"));
308 class_java_lang_Short =
309 class_new(utf_new_char("java/lang/Short"));
310 class_java_lang_Boolean =
311 class_new(utf_new_char("java/lang/Boolean"));
312 class_java_lang_Void =
313 class_new(utf_new_char("java/lang/Void"));
316 log_text("native_loadclasses finished");
320 /*************** adds a class to the vector of loaded classes ****************/
322 void systemclassloader_addclass(classinfo *c)
326 /* find method addClass of java.lang.ClassLoader */
327 m = class_resolvemethod(
328 class_java_lang_ClassLoader,
329 utf_new_char("addClass"),
330 utf_new_char("(Ljava/lang/Class;)")
333 if (!m) panic("warning: cannot initialize classloader");
335 /* prepare class to be passed as argument */
336 use_class_as_object (c);
338 /* call 'addClass' */
339 asm_calljavamethod(m,
340 (java_objectheader*) SystemClassLoader,
341 (java_objectheader*) c,
347 /*************** adds a library to the vector of loaded libraries *************/
349 void systemclassloader_addlibrary(java_objectheader *o)
351 log_text("systemclassloader_addlibrary");
354 /*****************************************************************************
356 create systemclassloader object and initialize instance fields
358 ******************************************************************************/
360 void init_systemclassloader()
362 if (!SystemClassLoader) {
363 native_loadclasses();
364 log_text("Initializing new system class loader");
365 /* create object and call initializer */
366 SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader);
367 heap_addreference((void**) &SystemClassLoader);
369 /* systemclassloader has no parent */
370 SystemClassLoader->parent = NULL;
371 SystemClassLoader->initialized = true;
373 log_text("leaving system class loader");
377 /********************* add loaded library name *******************************/
379 void systemclassloader_addlibname(java_objectheader *o)
384 m = class_resolvemethod(loader_load(utf_new_char ("java/util/Vector")),
385 utf_new_char("addElement"),
386 utf_new_char("(Ljava/lang/Object;)V")
389 if (!m) panic("cannot initialize classloader");
391 id = envTable.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
392 if (!id) panic("can not access ClassLoader");
394 asm_calljavamethod(m,
395 GetStaticObjectField(&env,class_java_lang_ClassLoader,id),
403 /********************* function: native_setclasspath **************************/
405 void native_setclasspath (char *path)
407 /* set searchpath for classfiles */
412 /***************** function: throw_classnotfoundexception *********************/
414 void throw_classnotfoundexception()
416 if (!class_java_lang_ClassNotFoundException) {
417 panic("java.lang.ClassNotFoundException not found. Maybe wrong classpath?");
420 /* throws a ClassNotFoundException */
421 exceptionptr = native_new_and_init(class_java_lang_ClassNotFoundException);
425 void throw_classnotfoundexception2(utf* classname)
427 if (!class_java_lang_ClassNotFoundException) {
428 panic("java.lang.ClassNotFoundException not found. Maybe wrong classpath?");
431 /* throws a ClassNotFoundException with message */
432 exceptionptr = native_new_and_init_string(class_java_lang_ClassNotFoundException,
433 javastring_new(classname));
436 void throw_linkageerror2(utf* classname)
438 if (!class_java_lang_LinkageError) {
439 panic("java.lang.LinkageError not found. Maybe wrong classpath?");
442 /* throws a ClassNotFoundException with message */
443 exceptionptr = native_new_and_init_string(class_java_lang_LinkageError,
444 javastring_new(classname));
448 /*********************** Function: native_findfunction *************************
450 Looks up a method (must have the same class name, method name, descriptor
451 and 'static'ness) and returns a function pointer to it.
452 Returns: function pointer or NULL (if there is no such method)
454 Remark: For faster operation, the names/descriptors are converted from C
455 strings to Unicode the first time this function is called.
457 *******************************************************************************/
459 functionptr native_findfunction(utf *cname, utf *mname,
460 utf *desc, bool isstatic)
463 /* entry of table for fast string comparison */
464 struct nativecompref *n;
465 /* for warning message if no function is found */
469 isstatic = isstatic ? true : false;
471 if (!nativecompdone) {
472 for (i = 0; i < NATIVETABLESIZE; i++) {
473 nativecomptable[i].classname =
474 utf_new_char(nativetable[i].classname);
475 nativecomptable[i].methodname =
476 utf_new_char(nativetable[i].methodname);
477 nativecomptable[i].descriptor =
478 utf_new_char(nativetable[i].descriptor);
479 nativecomptable[i].isstatic =
480 nativetable[i].isstatic;
481 nativecomptable[i].func =
484 nativecompdone = true;
489 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
491 buffer = MNEW(char, buffer_len);
493 strcpy(buffer, "searching matching function in native table:");
494 utf_sprint(buffer+strlen(buffer), mname);
495 strcpy(buffer+strlen(buffer), ": ");
496 utf_sprint(buffer+strlen(buffer), desc);
497 strcpy(buffer+strlen(buffer), " for class ");
498 utf_sprint(buffer+strlen(buffer), cname);
502 MFREE(buffer, char, buffer_len);
505 for (i = 0; i < NATIVETABLESIZE; i++) {
506 n = &(nativecomptable[i]);
508 if (cname == n->classname && mname == n->methodname &&
509 desc == n->descriptor && isstatic == n->isstatic)
513 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
517 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
519 buffer = MNEW(char, buffer_len);
521 strcpy(buffer, "comparing with:");
522 utf_sprint(buffer+strlen(buffer), n->methodname);
523 strcpy (buffer+strlen(buffer), ": ");
524 utf_sprint(buffer+strlen(buffer), n->descriptor);
525 strcpy(buffer+strlen(buffer), " for class ");
526 utf_sprint(buffer+strlen(buffer), n->classname);
530 MFREE(buffer, char, buffer_len);
538 /* no function was found, display warning */
541 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
543 buffer = MNEW(char, buffer_len);
545 strcpy(buffer, "warning: native function ");
546 utf_sprint(buffer + strlen(buffer), mname);
547 strcpy(buffer + strlen(buffer), ": ");
548 utf_sprint(buffer + strlen(buffer), desc);
549 strcpy(buffer + strlen(buffer), " not found in class ");
550 utf_sprint(buffer + strlen(buffer), cname);
554 MFREE(buffer, char, buffer_len);
564 /********************** function: javastring_new *******************************
566 creates a new object of type java/lang/String with the text of
567 the specified utf8-string
569 return: pointer to the string or NULL if memory is exhausted.
571 *******************************************************************************/
573 java_objectheader *javastring_new (utf *u)
575 char *utf_ptr = u->text; /* current utf character in utf string */
576 int utflength = utf_strlen(u); /* length of utf-string if uncompressed */
577 java_lang_String *s; /* result-string */
581 /* log_text("javastring_new");*/
583 s = (java_lang_String*) builtin_new (class_java_lang_String);
584 a = builtin_newarray_char (utflength);
586 /* javastring or character-array could not be created */
590 /* decompress utf-string */
591 for (i = 0; i < utflength; i++)
592 a->data[i] = utf_nextu2(&utf_ptr);
594 /* set fields of the javastring-object */
597 s->count = utflength;
599 return (java_objectheader*) s;
602 /********************** function: javastring_new_char **************************
604 creates a new java/lang/String object which contains the convertet
605 C-string passed via text.
607 return: the object pointer or NULL if memory is exhausted.
609 *******************************************************************************/
611 java_objectheader *javastring_new_char (char *text)
614 s4 len = strlen(text); /* length of the string */
615 java_lang_String *s; /* result-string */
618 /*log_text("javastring_new_char");*/
619 s = (java_lang_String*) builtin_new (class_java_lang_String);
620 a = builtin_newarray_char (len);
622 /* javastring or character-array could not be created */
623 if ((!a) || (!s)) return NULL;
626 for (i = 0; i < len; i++)
627 a->data[i] = text[i];
629 /* set fields of the javastring-object */
634 return (java_objectheader*) s;
638 /************************* function javastring_tochar **************************
640 converts a Java string into a C string.
642 return: pointer to C string
644 Caution: every call of this function overwrites the previous string !!!
646 *******************************************************************************/
648 static char stringbuffer[MAXSTRINGSIZE];
650 char *javastring_tochar (java_objectheader *so)
652 java_lang_String *s = (java_lang_String*) so;
656 log_text("javastring_tochar");
663 if (s->count > MAXSTRINGSIZE)
665 for (i = 0; i < s->count; i++)
666 stringbuffer[i] = a->data[s->offset+i];
667 stringbuffer[i] = '\0';
672 /****************** function class_findfield_approx ****************************
674 searches in 'classinfo'-structure for a field with the
677 *******************************************************************************/
679 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
682 for (i = 0; i < c->fieldscount; i++) {
683 /* compare field names */
684 if ((c->fields[i].name == name))
685 return &(c->fields[i]);
688 /* field was not found, raise exception */
689 exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException);
694 s4 class_findfield_index_approx (classinfo *c, utf *name)
697 for (i = 0; i < c->fieldscount; i++) {
698 /* compare field names */
699 if ((c->fields[i].name == name))
703 /* field was not found, raise exception */
704 exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException);
709 /********************** function: native_new_and_init *************************
711 Creates a new object on the heap and calls the initializer.
712 Returns the object pointer or NULL if memory is exhausted.
714 *******************************************************************************/
716 java_objectheader *native_new_and_init(classinfo *c)
719 java_objectheader *o = builtin_new(c); /* create object */
722 printf("native_new_and_init ");
723 utf_display(c->name);
727 /* printf("o!=NULL\n"); */
728 /* find initializer */
730 m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
732 if (!m) { /* initializer not found */
734 sprintf(logtext, "Warning: class has no instance-initializer: ");
735 utf_sprint(logtext + strlen(logtext), c->name);
741 /* call initializer */
743 asm_calljavamethod(m, o, NULL, NULL, NULL);
749 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
752 java_objectheader *o = builtin_new(c); /* create object */
756 /* find initializer */
758 m = class_findmethod(c,
759 utf_new_char("<init>"),
760 utf_new_char("(Ljava/lang/String;)V"));
762 if (!m) { /* initializer not found */
764 sprintf(logtext, "Warning: class has no instance-initializer: ");
765 utf_sprint(logtext + strlen(logtext), c->name);
771 /* call initializer */
773 asm_calljavamethod(m, o, s, NULL, NULL);
779 /******************** function: stringtable_update ****************************
781 traverses the javastring hashtable and sets the vftbl-entries of
782 javastrings which were temporarily set to NULL, because
783 java.lang.Object was not yet loaded
785 *******************************************************************************/
787 void stringtable_update ()
789 java_lang_String *js;
791 literalstring *s; /* hashtable entry */
794 for (i = 0; i < string_hash.size; i++) {
795 s = string_hash.ptr[i];
799 js = (java_lang_String *) s->string;
801 if (!js || !(a = js->value))
802 /* error in hashtable found */
803 panic("invalid literalstring in hashtable");
805 if (!js->header.vftbl)
806 /* vftbl of javastring is NULL */
807 js->header.vftbl = class_java_lang_String -> vftbl;
809 if (!a->header.objheader.vftbl)
810 /* vftbl of character-array is NULL */
811 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
813 /* follow link in external hash chain */
821 /************************* function: u2_utflength ***************************
823 returns the utf length in bytes of a u2 array
825 *****************************************************************************/
828 u4 u2_utflength(u2 *text, u4 u2_length)
830 u4 result_len = 0; /* utf length in bytes */
831 u2 ch; /* current unicode character */
834 for (len = 0; len < u2_length; len++) {
836 /* next unicode character */
839 /* determine bytes required to store unicode character as utf */
840 if (ch && (ch < 0x80))
851 /********************* function: utf_new_u2 ***********************************
853 make utf symbol from u2 array,
854 if isclassname is true '.' is replaced by '/'
856 *******************************************************************************/
858 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
860 char *buffer; /* memory buffer for unicode characters */
861 char *pos; /* pointer to current position in buffer */
862 u4 left; /* unicode characters left */
863 u4 buflength; /* utf length in bytes of the u2 array */
864 utf *result; /* resulting utf-string */
867 /* determine utf length in bytes and allocate memory */
868 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
869 buflength = u2_utflength(unicode_pos, unicode_length);
870 buffer = MNEW(char,buflength);
872 /* memory allocation failed */
874 printf("length: %d\n",buflength);
875 log_text("utf_new_u2:buffer==NULL");
881 for (i = 0; i++ < unicode_length; unicode_pos++) {
882 /* next unicode character */
885 if ((c != 0) && (c < 0x80)) {
888 if ((int) left < 0) break;
889 /* convert classname */
890 if (isclassname && c=='.')
894 } else if (c < 0x800) {
896 unsigned char high = c >> 6;
897 unsigned char low = c & 0x3F;
899 if ((int) left < 0) break;
900 *pos++ = high | 0xC0;
905 char mid = (c >> 6) & 0x3F;
908 if ((int) left < 0) break;
909 *pos++ = high | 0xE0;
915 /* insert utf-string into symbol-table */
916 result = utf_new(buffer,buflength);
918 MFREE(buffer, char, buflength);
922 /********************* function: javastring_toutf *****************************
924 make utf symbol from javastring
926 *******************************************************************************/
928 utf *javastring_toutf(java_lang_String *string, bool isclassname)
930 java_lang_String *str = (java_lang_String *) string;
931 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count);
933 return utf_new_u2(str->value->data+str->offset,str->count, isclassname);
936 /********************* function: literalstring_u2 *****************************
938 searches for the javastring with the specified u2-array in
939 the string hashtable, if there is no such string a new one is
942 if copymode is true a copy of the u2-array is made
944 *******************************************************************************/
946 java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode )
948 literalstring *s; /* hashtable element */
949 java_lang_String *js; /* u2-array wrapped in javastring */
950 java_chararray *stringdata; /* copy of u2-array */
956 printf("literalstring_u2: length: %d\n",length);
957 log_text("literalstring_u2");
960 /* find location in hashtable */
961 key = unicode_hashkey (a->data, length);
962 slot = key & (string_hash.size-1);
963 s = string_hash.ptr[slot];
967 js = (java_lang_String *) s->string;
969 if (js->count == length) {
971 for (i=0; i<length; i++)
972 if (js->value->data[i] != a->data[i]) goto nomatch;
974 /* string already in hashtable, free memory */
976 lit_mem_free(a, sizeof(java_chararray) + sizeof(u2)*(length-1)+10);
979 log_text("literalstring_u2: foundentry");
980 utf_display(javastring_toutf(js,0));
982 return (java_objectheader *) js;
986 /* follow link in external hash chain */
991 /* create copy of u2-array for new javastring */
992 u4 arraysize = sizeof(java_chararray) + sizeof(u2)*(length-1)+10;
993 stringdata = lit_mem_alloc ( arraysize );
994 memcpy(stringdata, a, arraysize );
999 /* location in hashtable found, complete arrayheader */
1000 stringdata -> header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
1001 stringdata -> header.size = length;
1003 /* create new javastring */
1004 js = LNEW (java_lang_String);
1005 js -> header.vftbl = class_java_lang_String -> vftbl;
1006 js -> value = stringdata;
1008 js -> count = length;
1010 /* create new literalstring */
1011 s = NEW (literalstring);
1012 s->hashlink = string_hash.ptr[slot];
1013 s->string = (java_objectheader *) js;
1014 string_hash.ptr[slot] = s;
1016 /* update numbe of hashtable entries */
1017 string_hash.entries++;
1019 /* reorganization of hashtable */
1020 if ( string_hash.entries > (string_hash.size*2)) {
1022 /* reorganization of hashtable, average length of
1023 the external chains is approx. 2 */
1027 hashtable newhash; /* the new hashtable */
1029 /* create new hashtable, double the size */
1030 init_hashtable(&newhash, string_hash.size*2);
1031 newhash.entries=string_hash.entries;
1033 /* transfer elements to new hashtable */
1034 for (i=0; i<string_hash.size; i++) {
1035 s = string_hash.ptr[i];
1037 literalstring *nexts = s -> hashlink;
1038 js = (java_lang_String*) s->string;
1039 slot = (unicode_hashkey(js->value->data,js->count)) & (newhash.size-1);
1041 s->hashlink = newhash.ptr[slot];
1042 newhash.ptr[slot] = s;
1044 /* follow link in external hash chain */
1049 /* dispose old table */
1050 MFREE (string_hash.ptr, void*, string_hash.size);
1051 string_hash = newhash;
1053 #ifdef JOWENN_DEBUG1
1054 log_text("literalstring_u2: newly created");
1055 /* utf_display(javastring_toutf(js,0));*/
1058 return (java_objectheader *) js;
1061 /******************** Function: literalstring_new *****************************
1063 creates a new javastring with the text of the utf-symbol
1064 and inserts it into the string hashtable
1066 *******************************************************************************/
1068 java_objectheader *literalstring_new (utf *u)
1070 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1071 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1072 java_chararray *a; /* u2-array constructed from utf string */
1074 /* log_text("literalstring_new"); */
1075 /* utf_display(u);*/
1076 /*if (utflength==0) while (1) sleep(60);*/
1077 /* log_text("------------------"); */
1078 /* allocate memory */
1079 a = lit_mem_alloc (sizeof(java_chararray) + sizeof(u2)*(utflength-1)+10 );
1080 /* convert utf-string to u2-array */
1081 for (i=0; i<utflength; i++) a->data[i] = utf_nextu2(&utf_ptr);
1083 return literalstring_u2(a, utflength, false);
1087 /********************** function: literalstring_free **************************
1089 removes a javastring from memory
1091 ******************************************************************************/
1093 void literalstring_free (java_objectheader* sobj)
1095 java_lang_String *s = (java_lang_String*) sobj;
1096 java_chararray *a = s->value;
1098 log_text("literalstring_free called");
1100 /* dispose memory of java.lang.String object */
1101 LFREE (s, java_lang_String);
1102 /* dispose memory of java-characterarray */
1103 LFREE (a, sizeof(java_chararray) + sizeof(u2)*(a->header.size-1)); /* +10 ?? */
1109 void copy_vftbl(vftbl **dest, vftbl *src)
1113 /* XXX this kind of copying does not work (in the general
1114 * case). The interface tables would have to be copied, too. I
1115 * don't see why we should make a copy anyway. -Edwin
1117 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1118 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1119 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1124 /******************************************************************************************
1126 creates method signature (excluding return type) from array of
1127 class-objects representing the parameters of the method
1129 *******************************************************************************************/
1132 utf *create_methodsig(java_objectarray* types, char *retType)
1134 char *buffer; /* buffer for building the desciptor */
1135 char *pos; /* current position in buffer */
1136 utf *result; /* the method signature */
1137 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1140 if (!types) return NULL;
1142 /* determine required buffer-size */
1143 for (i=0;i<types->header.size;i++) {
1144 classinfo *c = (classinfo *) types->data[i];
1145 buffer_size = buffer_size + c->name->blength+2;
1148 if (retType) buffer_size+=strlen(retType);
1150 /* allocate buffer */
1151 buffer = MNEW(u1, buffer_size);
1154 /* method-desciptor starts with parenthesis */
1157 for (i=0;i<types->header.size;i++) {
1160 /* current argument */
1161 classinfo *c = (classinfo *) types->data[i];
1162 /* current position in utf-text */
1163 char *utf_ptr = c->name->text;
1165 /* determine type of argument */
1166 if ( (ch = utf_nextu2(&utf_ptr)) == '[' ) {
1169 for ( utf_ptr--; utf_ptr<utf_end(c->name); utf_ptr++)
1170 *pos++ = *utf_ptr; /* copy text */
1174 /* check for primitive types */
1175 for (j=0; j<PRIMITIVETYPE_COUNT; j++) {
1177 char *utf_pos = utf_ptr-1;
1178 char *primitive = primitivetype_table[j].wrapname;
1181 while (utf_pos<utf_end(c->name))
1182 if (*utf_pos++ != *primitive++) goto nomatch;
1184 /* primitive type found */
1185 *pos++ = primitivetype_table[j].typesig;
1191 /* no primitive type and no arrayclass, so must be object */
1194 for ( utf_ptr--; utf_ptr<utf_end(c->name); utf_ptr++)
1205 for (i=0;i<strlen(retType);i++) {
1209 /* create utf-string */
1210 result = utf_new(buffer,(pos-buffer));
1211 MFREE(buffer, u1, buffer_size);
1217 /******************************************************************************************
1219 retrieve the next argument or returntype from a descriptor
1220 and return the corresponding class
1222 *******************************************************************************************/
1224 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1226 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1227 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1230 panic("illegal descriptor");
1232 if (skip) return NULL;
1234 use_class_as_object(c);
1239 /******************************************************************************************
1241 use the descriptor of a method to generate a java/lang/Class array
1242 which contains the classes of the parametertypes of the method
1244 *******************************************************************************************/
1246 java_objectarray* get_parametertypes(methodinfo *m)
1248 utf *descr = m->descriptor; /* method-descriptor */
1249 char *utf_ptr = descr->text; /* current position in utf-text */
1250 char *desc_end = utf_end(descr); /* points behind utf string */
1251 java_objectarray* result;
1252 int parametercount = 0;
1256 utf_nextu2(&utf_ptr);
1258 /* determine number of parameters */
1259 while ( *utf_ptr != ')' ) {
1260 get_type(&utf_ptr,desc_end,true);
1264 /* create class-array */
1265 result = builtin_anewarray(parametercount, class_java_lang_Class);
1267 utf_ptr = descr->text;
1268 utf_nextu2(&utf_ptr);
1270 /* get returntype classes */
1271 for (i = 0; i < parametercount; i++)
1272 result->data[i] = (java_objectheader *) get_type(&utf_ptr,desc_end, false);
1278 /******************************************************************************************
1280 get the returntype class of a method
1282 *******************************************************************************************/
1284 classinfo *get_returntype(methodinfo *m)
1286 char *utf_ptr; /* current position in utf-text */
1287 char *desc_end; /* points behind utf string */
1288 utf *desc = m->descriptor; /* method-descriptor */
1290 utf_ptr = desc->text;
1291 desc_end = utf_end(desc);
1293 /* ignore parametertypes */
1294 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1297 return get_type(&utf_ptr,desc_end, false);
1301 /*****************************************************************************/
1302 /*****************************************************************************/
1305 /*--------------------------------------------------------*/
1306 void printNativeCall(nativeCall nc) {
1309 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1310 for (i=0; i<nc.methCnt; i++) {
1311 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1313 for (j=0; j<nc.callCnt[i]; j++) {
1314 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1315 nc.methods[i].methodCalls[j].classname,
1316 nc.methods[i].methodCalls[j].methodname,
1317 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1320 printf("-+++++--------------------\n");fflush(stdout);
1323 /*--------------------------------------------------------*/
1324 void printCompNativeCall(nativeCompCall nc) {
1326 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1327 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1328 utf_display(nc.classname); fflush(stdout);
1330 for (i=0; i<nc.methCnt; i++) {
1331 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1332 utf_display(nc.methods[i].methodname); fflush(stdout);
1333 utf_display(nc.methods[i].descriptor);fflush(stdout);
1334 printf("\n");fflush(stdout);
1336 for (j=0; j<nc.callCnt[i]; j++) {
1337 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1338 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1339 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1340 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1341 printf("\n");fflush(stdout);
1344 printf("---------------------\n");fflush(stdout);
1348 /*--------------------------------------------------------*/
1349 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1362 /*--------------------------------------------------------*/
1363 nativeCall* findNativeClassCalls(char *aclassname ) {
1366 for (i=0;i<NATIVECALLSSIZE; i++) {
1367 /* convert table to utf later to speed up search */
1368 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1369 return &nativeCalls[i];
1374 /*--------------------------------------------------------*/
1375 /*--------------------------------------------------------*/
1376 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1380 ncc->classname = utf_new_char(nc.classname);
1381 ncc->methCnt = nc.methCnt;
1383 for (i=0; i<nc.methCnt; i++) {
1384 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1385 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1386 ncc->callCnt[i] = nc.callCnt[i];
1388 for (j=0; j<nc.callCnt[i]; j++) {
1390 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1392 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1393 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1394 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1397 ncc->methods[i].methodCalls[j].methodname = NULL;
1398 ncc->methods[i].methodCalls[j].descriptor = NULL;
1406 /*--------------------------------------------------------*/
1408 bool natcall2utf(bool natcallcompdone) {
1411 if (natcallcompdone)
1414 for (i=0;i<NATIVECALLSSIZE; i++) {
1415 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1420 /*--------------------------------------------------------*/
1424 * These are local overrides for various environment variables in Emacs.
1425 * Please do not remove this and leave it at the end of the file, where
1426 * Emacs will automagically detect them.
1427 * ---------------------------------------------------------------------
1430 * indent-tabs-mode: t