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 1021 2004-04-21 13:09:20Z stefan $
52 #include "nativetypes.hh"
58 #include "toolbox/loging.h"
59 #include "toolbox/memory.h"
60 #include "threads/thread.h"
61 #include "threads/threadio.h"
62 #include "threads/locks.h"
63 #include "nat/java_lang_VMClass.h"
64 #include "nat/java_lang_Throwable.h"
66 /* Include files for IO functions */
70 #include <sys/types.h>
76 #include "threads/threadio.h"
78 /* searchpath for classfiles */
81 /* for java-string to char conversion */
82 #define MAXSTRINGSIZE 1000
84 /******************** systemclasses required for native methods ***************/
86 classinfo *class_java_lang_Class;
87 classinfo *class_java_lang_VMClass;
88 /* static classinfo *class_java_lang_Cloneable=0; */ /* now in global.h */
89 classinfo *class_java_lang_System;
90 classinfo *class_java_lang_ClassLoader;
91 classinfo *class_gnu_java_lang_SystemClassLoader;
92 classinfo *class_java_lang_SecurityManager;
93 classinfo *class_java_lang_Double;
94 classinfo *class_java_lang_Float;
95 classinfo *class_java_lang_Long;
96 classinfo *class_java_lang_Byte;
97 classinfo *class_java_lang_Short;
98 classinfo *class_java_lang_Boolean;
99 classinfo *class_java_lang_Void;
100 classinfo *class_java_lang_Character;
101 classinfo *class_java_lang_Integer;
103 methodinfo *method_vmclass_init;
106 /* specify some exception strings for code generation */
108 char *string_java_lang_ArithmeticException =
109 "java/lang/ArithmeticException";
111 char *string_java_lang_ArithmeticException_message =
114 char *string_java_lang_ArrayIndexOutOfBoundsException =
115 "java/lang/ArrayIndexOutOfBoundsException";
117 char *string_java_lang_ArrayStoreException =
118 "java/lang/ArrayStoreException";
120 char *string_java_lang_ClassCastException =
121 "java/lang/ClassCastException";
123 char *string_java_lang_ClassNotFoundException =
124 "java/lang/ClassNotFoundException";
126 char *string_java_lang_CloneNotSupportedException =
127 "java/lang/CloneNotSupportedException";
129 char *string_java_lang_IllegalArgumentException =
130 "java/lang/IllegalArgumentException";
132 char *string_java_lang_NegativeArraySizeException =
133 "java/lang/NegativeArraySizeException";
135 char *string_java_lang_NoSuchFieldException =
136 "java/lang/NoSuchFieldException";
138 char *string_java_lang_NoSuchMethodException =
139 "java/lang/NoSuchMethodException";
141 char *string_java_lang_NullPointerException =
142 "java/lang/NullPointerException";
145 /* specify some error strings for code generation */
147 char *string_java_lang_ClassFormatError =
148 "java/lang/ClassFormatError";
150 char *string_java_lang_LinkageError =
151 "java/lang/LinkageError";
153 char *string_java_lang_NoClassDefFoundError =
154 "java/lang/NoClassDefFoundError";
156 char *string_java_lang_NoSuchFieldError =
157 "java/lang/NoSuchFieldError";
159 char *string_java_lang_NoSuchMethodError =
160 "java/lang/NoSuchMethodError";
162 char *string_java_lang_OutOfMemoryError =
163 "java/lang/OutOfMemoryError";
166 /* the system classloader object */
167 struct java_lang_ClassLoader *SystemClassLoader = NULL;
169 /* for raising exceptions from native methods */
170 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
171 java_objectheader* _exceptionptr = NULL;
174 /************* use classinfo structure as java.lang.Class object **************/
176 void use_class_as_object(classinfo *c)
181 if (!class_java_lang_Class)
182 class_java_lang_Class = class_new(utf_new_char ("java/lang/Class"));
184 vt = class_java_lang_Class->vftbl;
187 if (!c->classvftbl) {
188 c->classvftbl = true;
190 /* copy_vftbl(&newtbl, vt);
191 newtbl->class = c->header.vftbl->class;
192 newtbl->baseval = c->header.vftbl->baseval;
193 newtbl->diffval = c->header.vftbl->diffval;
194 c->header.vftbl = newtbl;*/
196 c->header.vftbl = class_java_lang_Class->vftbl;
198 if (!class_java_lang_VMClass) {
199 loader_load_sysclass(&class_java_lang_VMClass,
200 utf_new_char("java/lang/VMClass"));
202 method_vmclass_init =
203 class_findmethod(class_java_lang_VMClass,
204 utf_new_char("<init>"),
205 utf_new_char("(Lgnu/classpath/RawData;)V"));
207 if (method_vmclass_init == 0) {
208 class_showmethods(class_java_lang_VMClass);
209 panic("Needed class initializer for VMClass could not be found");
213 java_objectheader *vmo = builtin_new(class_java_lang_VMClass);
215 if (!vmo) panic("Error while creating instance of java/lang/VMClass");
216 asm_calljavafunction(method_vmclass_init, vmo, c, NULL, NULL);
217 c->vmClass = (java_lang_VMClass *) vmo;
218 /*log_text("VMCLASS has been attached");*/
224 /*************************** include native methods ***************************/
227 #include "nat/GdkGraphics.c"
228 #include "nat/GtkComponentPeer.c"
229 #include "nat/GdkPixbufDecoder.c"
230 #include "nat/GtkScrollPanePeer.c"
231 #include "nat/GtkFileDialogPeer.c"
232 #include "nat/GtkLabelPeer.c"
236 /************************** tables for methods ********************************/
241 /* table for locating native methods */
242 static struct nativeref {
250 #include "nativetable.hh"
255 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
257 /* table for fast string comparison */
258 static struct nativecompref {
264 } nativecomptable [NATIVETABLESIZE];
266 /* string comparsion table initialized */
267 static bool nativecompdone = false;
270 /******************************************************************************/
271 /******************************************************************************/
272 #include "natcalls.h"
274 /* string call comparison table initialized */
276 /******************************************************************************/
277 /******************************************************************************/
279 /*--------------- native method calls & classes used -------------------------*/
281 void throw_exception_exit()
283 java_lang_String *message;
286 printf("Exception in thread \"main\" ");
287 utf_display_classname((*exceptionptr)->vftbl->class->name);
289 /* do we have a detail message? */
290 message = ((java_lang_Throwable *) *exceptionptr)->detailMessage;
294 utf_display(javastring_toutf(message, false));
299 /* clear exception, whatever... */
300 *exceptionptr = NULL;
308 java_objectheader *new_exception(char *classname)
310 classinfo *c = class_new(utf_new_char(classname));
313 printf("Exception class %s not linked! You probably have not set your CLASSPATH properly.\n", classname);
317 return native_new_and_init(c);
320 java_objectheader *new_exception_message(char *classname, char *message)
322 classinfo *c = class_new(utf_new_char(classname));
325 printf("Exception class %s not linked! You probably have not set your CLASSPATH properly.\n", classname);
329 return native_new_and_init_string(c, javastring_new_char(message));
333 java_objectheader *new_exception_utfmessage(char *classname, utf *message)
335 classinfo *c = class_new(utf_new_char(classname));
338 printf("Exception class %s not linked! You probably have not set your CLASSPATH properly.\n", classname);
342 return native_new_and_init_string(c, javastring_new(message));
346 java_objectheader *new_exception_javastring(char *classname, java_lang_String *message)
348 classinfo *c = class_new(utf_new_char(classname));
351 printf("Exception class %s not linked! You probably have not set your CLASSPATH properly.\n", classname);
355 return native_new_and_init_string(c, message);
359 java_objectheader *new_exception_int(char *classname, s4 i)
361 classinfo *c = class_new(utf_new_char(classname));
364 printf("Exception class %s not linked! You probably have not set your CLASSPATH properly.\n", classname);
368 return native_new_and_init_int(c, i);
372 /*********************** function: native_loadclasses **************************
374 load classes required for native methods
376 *******************************************************************************/
378 void native_loadclasses()
380 static int classesLoaded=0; /*temporary hack JoWenn*/
381 if (classesLoaded) return;
384 /*class_java_lang_System =*/
385 (void) class_new(utf_new_char("java/lang/VMClass"));/*JoWenn*/
386 (void) class_new(utf_new_char("java/lang/Class"));/*JoWenn*/
388 /* class_new adds the class to the list of classes to be loaded */
389 if (!class_java_lang_Cloneable)
390 class_java_lang_Cloneable =
391 class_new(utf_new_char("java/lang/Cloneable"));
393 if (!class_java_lang_Class)
394 class_java_lang_Class =
395 class_new(utf_new_char("java/lang/Class"));
397 class_java_lang_ClassLoader =
398 class_new(utf_new_char("java/lang/ClassLoader"));
400 /* load classes for wrapping primitive types */
401 class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
402 class_init(class_java_lang_Double);
404 class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
405 class_java_lang_Character = class_new(utf_new_char("java/lang/Character"));
406 class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
407 class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
408 class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
409 class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
410 class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
411 class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
417 /*************** adds a class to the vector of loaded classes ****************/
419 void systemclassloader_addclass(classinfo *c)
423 /* find method addClass of java.lang.ClassLoader */
424 m = class_resolvemethod(class_java_lang_ClassLoader,
425 utf_new_char("addClass"),
426 utf_new_char("(Ljava/lang/Class;)")
430 panic("warning: cannot initialize classloader");
432 /* prepare class to be passed as argument */
433 use_class_as_object (c);
435 /* call 'addClass' */
436 asm_calljavafunction(m,
437 (java_objectheader*) SystemClassLoader,
438 (java_objectheader*) c,
445 /*************** adds a library to the vector of loaded libraries *************/
447 void systemclassloader_addlibrary(java_objectheader *o)
449 log_text("systemclassloader_addlibrary");
453 /*****************************************************************************
455 create systemclassloader object and initialize instance fields
457 ******************************************************************************/
459 void init_systemclassloader()
461 log_text("init_systemclassloader");
462 if (!SystemClassLoader) {
463 native_loadclasses();
464 log_text("Initializing new system class loader");
465 /* create object and call initializer */
466 SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
468 /* systemclassloader has no parent */
469 SystemClassLoader->parent = NULL;
470 SystemClassLoader->initialized = true;
472 log_text("leaving system class loader");
476 /********************* add loaded library name *******************************/
478 void systemclassloader_addlibname(java_objectheader *o)
483 m = class_resolvemethod(loader_load_sysclass(NULL, utf_new_char("java/util/Vector")),
484 utf_new_char("addElement"),
485 utf_new_char("(Ljava/lang/Object;)V"));
487 if (!m) panic("cannot initialize classloader");
489 id = envTable.GetStaticFieldID(&env,
490 class_java_lang_ClassLoader,
491 "loadedLibraryNames",
492 "Ljava/util/Vector;");
494 if (!id) panic("can not access ClassLoader");
496 asm_calljavafunction(m,
497 envTable.GetStaticObjectField(&env, class_java_lang_ClassLoader, id),
504 /********************* function: native_setclasspath **************************/
506 void native_setclasspath(char *path)
508 /* set searchpath for classfiles */
513 /*********************** Function: native_findfunction *************************
515 Looks up a method (must have the same class name, method name, descriptor
516 and 'static'ness) and returns a function pointer to it.
517 Returns: function pointer or NULL (if there is no such method)
519 Remark: For faster operation, the names/descriptors are converted from C
520 strings to Unicode the first time this function is called.
522 *******************************************************************************/
524 functionptr native_findfunction(utf *cname, utf *mname,
525 utf *desc, bool isstatic)
528 /* entry of table for fast string comparison */
529 struct nativecompref *n;
530 /* for warning message if no function is found */
534 isstatic = isstatic ? true : false;
536 if (!nativecompdone) {
537 for (i = 0; i < NATIVETABLESIZE; i++) {
538 nativecomptable[i].classname =
539 utf_new_char(nativetable[i].classname);
540 nativecomptable[i].methodname =
541 utf_new_char(nativetable[i].methodname);
542 nativecomptable[i].descriptor =
543 utf_new_char(nativetable[i].descriptor);
544 nativecomptable[i].isstatic =
545 nativetable[i].isstatic;
546 nativecomptable[i].func =
549 nativecompdone = true;
554 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
556 buffer = MNEW(char, buffer_len);
558 strcpy(buffer, "searching matching function in native table:");
559 utf_sprint(buffer+strlen(buffer), mname);
560 strcpy(buffer+strlen(buffer), ": ");
561 utf_sprint(buffer+strlen(buffer), desc);
562 strcpy(buffer+strlen(buffer), " for class ");
563 utf_sprint(buffer+strlen(buffer), cname);
567 MFREE(buffer, char, buffer_len);
570 for (i = 0; i < NATIVETABLESIZE; i++) {
571 n = &(nativecomptable[i]);
573 if (cname == n->classname && mname == n->methodname &&
574 desc == n->descriptor && isstatic == n->isstatic)
578 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
582 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
584 buffer = MNEW(char, buffer_len);
586 strcpy(buffer, "comparing with:");
587 utf_sprint(buffer+strlen(buffer), n->methodname);
588 strcpy (buffer+strlen(buffer), ": ");
589 utf_sprint(buffer+strlen(buffer), n->descriptor);
590 strcpy(buffer+strlen(buffer), " for class ");
591 utf_sprint(buffer+strlen(buffer), n->classname);
595 MFREE(buffer, char, buffer_len);
602 /* no function was found, display warning */
605 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
607 buffer = MNEW(char, buffer_len);
609 strcpy(buffer, "warning: native function ");
610 utf_sprint(buffer + strlen(buffer), mname);
611 strcpy(buffer + strlen(buffer), ": ");
612 utf_sprint(buffer + strlen(buffer), desc);
613 strcpy(buffer + strlen(buffer), " not found in class ");
614 utf_sprint(buffer + strlen(buffer), cname);
618 MFREE(buffer, char, buffer_len);
622 /* keep compiler happy */
627 /********************** function: javastring_new *******************************
629 creates a new object of type java/lang/String with the text of
630 the specified utf8-string
632 return: pointer to the string or NULL if memory is exhausted.
634 *******************************************************************************/
636 /* java_objectheader *javastring_new(utf *u) */
637 java_lang_String *javastring_new(utf *u)
639 char *utf_ptr = u->text; /* current utf character in utf string */
640 int utflength = utf_strlen(u); /* length of utf-string if uncompressed */
641 java_lang_String *s; /* result-string */
645 /* log_text("javastring_new");*/
647 s = (java_lang_String*) builtin_new(class_java_lang_String);
648 a = builtin_newarray_char(utflength);
650 /* javastring or character-array could not be created */
654 /* decompress utf-string */
655 for (i = 0; i < utflength; i++)
656 a->data[i] = utf_nextu2(&utf_ptr);
658 /* set fields of the javastring-object */
661 s->count = utflength;
663 /* return (java_objectheader*) s; */
668 /********************** function: javastring_new_char **************************
670 creates a new java/lang/String object which contains the convertet
671 C-string passed via text.
673 return: the object pointer or NULL if memory is exhausted.
675 *******************************************************************************/
677 java_lang_String *javastring_new_char(char *text)
680 s4 len = strlen(text); /* length of the string */
681 java_lang_String *s; /* result-string */
684 /*log_text("javastring_new_char");*/
685 s = (java_lang_String *) builtin_new(class_java_lang_String);
686 a = builtin_newarray_char(len);
688 /* javastring or character-array could not be created */
693 for (i = 0; i < len; i++)
694 a->data[i] = text[i];
696 /* set fields of the javastring-object */
701 /* return (java_objectheader*) s; */
706 /************************* function javastring_tochar **************************
708 converts a Java string into a C string.
710 return: pointer to C string
712 Caution: every call of this function overwrites the previous string !!!
714 *******************************************************************************/
716 static char stringbuffer[MAXSTRINGSIZE];
718 char *javastring_tochar(java_objectheader *so)
720 java_lang_String *s = (java_lang_String *) so;
732 if (s->count > MAXSTRINGSIZE)
735 for (i = 0; i < s->count; i++)
736 stringbuffer[i] = a->data[s->offset + i];
738 stringbuffer[i] = '\0';
744 /****************** function class_findfield_approx ****************************
746 searches in 'classinfo'-structure for a field with the
749 *******************************************************************************/
751 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
755 for (i = 0; i < c->fieldscount; i++) {
756 /* compare field names */
757 if ((c->fields[i].name == name))
758 return &(c->fields[i]);
761 /* field was not found, raise exception */
762 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
768 s4 class_findfield_index_approx(classinfo *c, utf *name)
772 for (i = 0; i < c->fieldscount; i++) {
773 /* compare field names */
774 if ((c->fields[i].name == name))
778 /* field was not found, raise exception */
779 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
785 /********************** function: native_new_and_init *************************
787 Creates a new object on the heap and calls the initializer.
788 Returns the object pointer or NULL if memory is exhausted.
790 *******************************************************************************/
792 java_objectheader *native_new_and_init(classinfo *c)
795 java_objectheader *o;
797 /* if c==NULL it is probebly because loader_load failed */
798 if (!c) return *exceptionptr;
800 o = builtin_new(c); /* create object */
803 printf("native_new_and_init ");
804 utf_display(c->name);
808 /* printf("o!=NULL\n"); */
809 /* find initializer */
811 m = class_findmethod(c,
812 utf_new_char("<init>"),
813 utf_new_char("()V"));
815 if (!m) { /* initializer not found */
817 char logtext[MAXLOGTEXT];
818 sprintf(logtext, "Warning: class has no instance-initializer: ");
819 utf_sprint(logtext + strlen(logtext), c->name);
825 /* call initializer */
827 asm_calljavafunction(m, o, NULL, NULL, NULL);
833 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
836 java_objectheader *o;
838 /* if c==NULL it is probebly because loader_load failed */
839 if (!c) return *exceptionptr;
841 o = builtin_new(c); /* create object */
845 /* find initializer */
847 m = class_findmethod(c,
848 utf_new_char("<init>"),
849 utf_new_char("(Ljava/lang/String;)V"));
851 if (!m) { /* initializer not found */
853 char logtext[MAXLOGTEXT];
854 sprintf(logtext, "Warning: class has no instance-initializer: ");
855 utf_sprint(logtext + strlen(logtext), c->name);
861 /* call initializer */
863 asm_calljavafunction(m, o, s, NULL, NULL);
869 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
872 java_objectheader *o;
874 /* if c == NULL it is probebly because loader_load failed */
875 if (!c) return *exceptionptr;
877 o = builtin_new(c); /* create object */
881 /* find initializer */
883 m = class_findmethod(c,
884 utf_new_char("<init>"),
885 utf_new_char("(I)V"));
887 if (!m) { /* initializer not found */
889 char logtext[MAXLOGTEXT];
890 sprintf(logtext, "Warning: class has no instance-initializer: ");
891 utf_sprint(logtext + strlen(logtext), c->name);
897 /* call initializer */
899 asm_calljavafunction(m, o, (void *) i, NULL, NULL);
905 /******************** function: stringtable_update ****************************
907 traverses the javastring hashtable and sets the vftbl-entries of
908 javastrings which were temporarily set to NULL, because
909 java.lang.Object was not yet loaded
911 *******************************************************************************/
913 void stringtable_update ()
915 java_lang_String *js;
917 literalstring *s; /* hashtable entry */
920 for (i = 0; i < string_hash.size; i++) {
921 s = string_hash.ptr[i];
925 js = (java_lang_String *) s->string;
927 if (!js || !js->value)
928 /* error in hashtable found */
929 panic("invalid literalstring in hashtable");
933 if (!js->header.vftbl)
934 /* vftbl of javastring is NULL */
935 js->header.vftbl = class_java_lang_String -> vftbl;
937 if (!a->header.objheader.vftbl)
938 /* vftbl of character-array is NULL */
939 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
941 /* follow link in external hash chain */
949 /************************* function: u2_utflength ***************************
951 returns the utf length in bytes of a u2 array
953 *****************************************************************************/
955 u4 u2_utflength(u2 *text, u4 u2_length)
957 u4 result_len = 0; /* utf length in bytes */
958 u2 ch; /* current unicode character */
961 for (len = 0; len < u2_length; len++) {
962 /* next unicode character */
965 /* determine bytes required to store unicode character as utf */
966 if (ch && (ch < 0x80))
978 /********************* function: utf_new_u2 ***********************************
980 make utf symbol from u2 array,
981 if isclassname is true '.' is replaced by '/'
983 *******************************************************************************/
985 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
987 char *buffer; /* memory buffer for unicode characters */
988 char *pos; /* pointer to current position in buffer */
989 u4 left; /* unicode characters left */
990 u4 buflength; /* utf length in bytes of the u2 array */
991 utf *result; /* resulting utf-string */
994 /* determine utf length in bytes and allocate memory */
995 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
996 buflength = u2_utflength(unicode_pos, unicode_length);
997 buffer = MNEW(char, buflength);
999 /* memory allocation failed */
1001 printf("length: %d\n",buflength);
1002 log_text("utf_new_u2:buffer==NULL");
1008 for (i = 0; i++ < unicode_length; unicode_pos++) {
1009 /* next unicode character */
1010 u2 c = *unicode_pos;
1012 if ((c != 0) && (c < 0x80)) {
1015 if ((int) left < 0) break;
1016 /* convert classname */
1017 if (isclassname && c == '.')
1022 } else if (c < 0x800) {
1024 unsigned char high = c >> 6;
1025 unsigned char low = c & 0x3F;
1027 if ((int) left < 0) break;
1028 *pos++ = high | 0xC0;
1029 *pos++ = low | 0x80;
1033 char low = c & 0x3f;
1034 char mid = (c >> 6) & 0x3F;
1035 char high = c >> 12;
1037 if ((int) left < 0) break;
1038 *pos++ = high | 0xE0;
1039 *pos++ = mid | 0x80;
1040 *pos++ = low | 0x80;
1044 /* insert utf-string into symbol-table */
1045 result = utf_new(buffer,buflength);
1047 MFREE(buffer, char, buflength);
1053 /********************* function: javastring_toutf *****************************
1055 make utf symbol from javastring
1057 *******************************************************************************/
1059 utf *javastring_toutf(java_lang_String *string, bool isclassname)
1061 java_lang_String *str = (java_lang_String *) string;
1063 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
1064 /* fflush(stdout); */
1066 return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
1070 /********************* function: literalstring_u2 *****************************
1072 searches for the javastring with the specified u2-array in
1073 the string hashtable, if there is no such string a new one is
1076 if copymode is true a copy of the u2-array is made
1078 *******************************************************************************/
1080 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
1083 literalstring *s; /* hashtable element */
1084 java_lang_String *js; /* u2-array wrapped in javastring */
1085 java_chararray *stringdata; /* copy of u2-array */
1090 //#define DEBUG_LITERALSTRING_U2
1091 #ifdef DEBUG_LITERALSTRING_U2
1092 printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
1096 /* find location in hashtable */
1097 key = unicode_hashkey(a->data + offset, length);
1098 slot = key & (string_hash.size - 1);
1099 s = string_hash.ptr[slot];
1102 js = (java_lang_String *) s->string;
1104 if (length == js->count) {
1106 for (i = 0; i < length; i++) {
1107 if (a->data[offset + i] != js->value->data[i])
1111 /* string already in hashtable, free memory */
1113 lit_mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
1115 #ifdef DEBUG_LITERALSTRING_U2
1116 printf("literalstring_u2: foundentry at %p\n", js);
1117 utf_display(javastring_toutf(js, 0));
1121 return (java_objectheader *) js;
1125 /* follow link in external hash chain */
1130 /* create copy of u2-array for new javastring */
1131 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
1132 stringdata = lit_mem_alloc(arraysize);
1133 /* memcpy(stringdata, a, arraysize); */
1134 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
1135 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
1141 /* location in hashtable found, complete arrayheader */
1142 stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
1143 stringdata->header.size = length;
1145 /* create new javastring */
1146 js = LNEW(java_lang_String);
1147 js->header.vftbl = class_java_lang_String->vftbl;
1148 js->value = stringdata;
1152 /* create new literalstring */
1153 s = NEW(literalstring);
1154 s->hashlink = string_hash.ptr[slot];
1155 s->string = (java_objectheader *) js;
1156 string_hash.ptr[slot] = s;
1158 /* update numbe of hashtable entries */
1159 string_hash.entries++;
1161 /* reorganization of hashtable */
1162 if (string_hash.entries > (string_hash.size * 2)) {
1163 /* reorganization of hashtable, average length of
1164 the external chains is approx. 2 */
1168 hashtable newhash; /* the new hashtable */
1170 /* create new hashtable, double the size */
1171 init_hashtable(&newhash, string_hash.size * 2);
1172 newhash.entries = string_hash.entries;
1174 /* transfer elements to new hashtable */
1175 for (i = 0; i < string_hash.size; i++) {
1176 s = string_hash.ptr[i];
1178 literalstring *nexts = s->hashlink;
1179 js = (java_lang_String *) s->string;
1180 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
1182 s->hashlink = newhash.ptr[slot];
1183 newhash.ptr[slot] = s;
1185 /* follow link in external hash chain */
1190 /* dispose old table */
1191 MFREE(string_hash.ptr, void*, string_hash.size);
1192 string_hash = newhash;
1195 #ifdef DEBUG_LITERALSTRING_U2
1196 printf("literalstring_u2: newly created at %p\n", js);
1197 utf_display(javastring_toutf(js, 0));
1202 return (java_objectheader *) js;
1206 /******************** Function: literalstring_new *****************************
1208 creates a new javastring with the text of the utf-symbol
1209 and inserts it into the string hashtable
1211 *******************************************************************************/
1213 java_objectheader *literalstring_new(utf *u)
1215 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1216 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1217 java_chararray *a; /* u2-array constructed from utf string */
1219 /* log_text("literalstring_new"); */
1220 /* utf_display(u);*/
1221 /*if (utflength==0) while (1) sleep(60);*/
1222 /* log_text("------------------"); */
1223 /* allocate memory */
1224 a = lit_mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1226 /* convert utf-string to u2-array */
1227 for (i = 0; i < utflength; i++)
1228 a->data[i] = utf_nextu2(&utf_ptr);
1230 return literalstring_u2(a, utflength, 0, false);
1234 /********************** function: literalstring_free **************************
1236 removes a javastring from memory
1238 ******************************************************************************/
1240 void literalstring_free(java_objectheader* sobj)
1242 java_lang_String *s = (java_lang_String *) sobj;
1243 java_chararray *a = s->value;
1245 log_text("literalstring_free called");
1247 /* dispose memory of java.lang.String object */
1248 LFREE(s, java_lang_String);
1250 /* dispose memory of java-characterarray */
1251 LFREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1255 void copy_vftbl(vftbl **dest, vftbl *src)
1259 /* XXX this kind of copying does not work (in the general
1260 * case). The interface tables would have to be copied, too. I
1261 * don't see why we should make a copy anyway. -Edwin
1263 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1264 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1265 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1270 /******************************************************************************************
1272 creates method signature (excluding return type) from array of
1273 class-objects representing the parameters of the method
1275 *******************************************************************************************/
1278 utf *create_methodsig(java_objectarray* types, char *retType)
1280 char *buffer; /* buffer for building the desciptor */
1281 char *pos; /* current position in buffer */
1282 utf *result; /* the method signature */
1283 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1286 if (!types) return NULL;
1288 /* determine required buffer-size */
1289 for (i = 0; i < types->header.size; i++) {
1290 classinfo *c = (classinfo *) types->data[i];
1291 buffer_size = buffer_size + c->name->blength + 2;
1294 if (retType) buffer_size += strlen(retType);
1296 /* allocate buffer */
1297 buffer = MNEW(u1, buffer_size);
1300 /* method-desciptor starts with parenthesis */
1303 for (i = 0; i < types->header.size; i++) {
1306 /* current argument */
1307 classinfo *c = (classinfo *) types->data[i];
1309 /* current position in utf-text */
1310 char *utf_ptr = c->name->text;
1312 /* determine type of argument */
1313 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1315 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1316 *pos++ = *utf_ptr; /* copy text */
1321 /* check for primitive types */
1322 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1323 char *utf_pos = utf_ptr - 1;
1324 char *primitive = primitivetype_table[j].wrapname;
1327 while (utf_pos < utf_end(c->name)) {
1328 if (*utf_pos++ != *primitive++) goto nomatch;
1331 /* primitive type found */
1332 *pos++ = primitivetype_table[j].typesig;
1336 /* GCC 3.4 needs this */
1340 /* no primitive type and no arrayclass, so must be object */
1344 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1351 /* GCC 3.4 needs this */
1359 for (i = 0; i < strlen(retType); i++) {
1360 *pos++ = retType[i];
1364 /* create utf-string */
1365 result = utf_new(buffer, (pos - buffer));
1366 MFREE(buffer, u1, buffer_size);
1372 /******************************************************************************************
1374 retrieve the next argument or returntype from a descriptor
1375 and return the corresponding class
1377 *******************************************************************************************/
1379 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1381 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1382 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1385 panic("illegal descriptor");
1387 if (skip) return NULL;
1389 use_class_as_object(c);
1394 /******************************************************************************************
1396 use the descriptor of a method to generate a java/lang/Class array
1397 which contains the classes of the parametertypes of the method
1399 *******************************************************************************************/
1401 java_objectarray* get_parametertypes(methodinfo *m)
1403 utf *descr = m->descriptor; /* method-descriptor */
1404 char *utf_ptr = descr->text; /* current position in utf-text */
1405 char *desc_end = utf_end(descr); /* points behind utf string */
1406 java_objectarray* result;
1407 int parametercount = 0;
1411 utf_nextu2(&utf_ptr);
1413 /* determine number of parameters */
1414 while ( *utf_ptr != ')' ) {
1415 get_type(&utf_ptr,desc_end,true);
1419 /* create class-array */
1420 result = builtin_anewarray(parametercount, class_java_lang_Class);
1422 utf_ptr = descr->text;
1423 utf_nextu2(&utf_ptr);
1425 /* get returntype classes */
1426 for (i = 0; i < parametercount; i++)
1427 result->data[i] = (java_objectheader *) get_type(&utf_ptr,desc_end, false);
1436 /******************************************************************************************
1438 get the exceptions which can be thrown by a method
1440 *******************************************************************************************/
1442 java_objectarray* get_exceptiontypes(methodinfo *m) {
1443 u2 exccount=m->thrownexceptionscount;
1445 java_objectarray *result;
1446 /* create class-array */
1447 result = builtin_anewarray(exccount, class_java_lang_Class);
1448 for (i=0;i<exccount;i++) {
1449 java_objectheader *oh=(java_objectheader*)(m->thrownexceptions[i]);
1450 use_class_as_object(oh);
1460 /******************************************************************************************
1462 get the returntype class of a method
1464 *******************************************************************************************/
1466 classinfo *get_returntype(methodinfo *m)
1468 char *utf_ptr; /* current position in utf-text */
1469 char *desc_end; /* points behind utf string */
1470 utf *desc = m->descriptor; /* method-descriptor */
1472 utf_ptr = desc->text;
1473 desc_end = utf_end(desc);
1475 /* ignore parametertypes */
1476 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1479 return get_type(&utf_ptr,desc_end, false);
1483 /*****************************************************************************/
1484 /*****************************************************************************/
1487 /*--------------------------------------------------------*/
1488 void printNativeCall(nativeCall nc) {
1491 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1492 for (i=0; i<nc.methCnt; i++) {
1493 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1495 for (j=0; j<nc.callCnt[i]; j++) {
1496 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1497 nc.methods[i].methodCalls[j].classname,
1498 nc.methods[i].methodCalls[j].methodname,
1499 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1502 printf("-+++++--------------------\n");fflush(stdout);
1505 /*--------------------------------------------------------*/
1506 void printCompNativeCall(nativeCompCall nc) {
1508 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1509 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1510 utf_display(nc.classname); fflush(stdout);
1512 for (i=0; i<nc.methCnt; i++) {
1513 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1514 utf_display(nc.methods[i].methodname); fflush(stdout);
1515 utf_display(nc.methods[i].descriptor);fflush(stdout);
1516 printf("\n");fflush(stdout);
1518 for (j=0; j<nc.callCnt[i]; j++) {
1519 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1520 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1521 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1522 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1523 printf("\n");fflush(stdout);
1526 printf("---------------------\n");fflush(stdout);
1530 /*--------------------------------------------------------*/
1531 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1544 /*--------------------------------------------------------*/
1545 nativeCall* findNativeClassCalls(char *aclassname ) {
1548 for (i=0;i<NATIVECALLSSIZE; i++) {
1549 /* convert table to utf later to speed up search */
1550 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1551 return &nativeCalls[i];
1556 /*--------------------------------------------------------*/
1557 /*--------------------------------------------------------*/
1558 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1562 ncc->classname = utf_new_char(nc.classname);
1563 ncc->methCnt = nc.methCnt;
1565 for (i=0; i<nc.methCnt; i++) {
1566 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1567 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1568 ncc->callCnt[i] = nc.callCnt[i];
1570 for (j=0; j<nc.callCnt[i]; j++) {
1572 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1574 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1575 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1576 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1579 ncc->methods[i].methodCalls[j].methodname = NULL;
1580 ncc->methods[i].methodCalls[j].descriptor = NULL;
1588 /*--------------------------------------------------------*/
1590 bool natcall2utf(bool natcallcompdone) {
1593 if (natcallcompdone)
1596 for (i=0;i<NATIVECALLSSIZE; i++) {
1597 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1603 /*--------------------------------------------------------*/
1606 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end,classinfo **start) {
1607 #warning platform dependend
1608 java_objectarray *tmpArray;
1610 classinfo **current;
1612 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1613 /* printf("end %p, start %p, size %ld\n",end,start,size);*/
1614 if (!class_java_lang_Class)
1615 class_java_lang_Class = class_new(utf_new_char ("java/lang/Class"));
1616 if (!class_java_lang_SecurityManager)
1617 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1619 if (start==class_java_lang_SecurityManager) {
1624 tmpArray=builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1626 for(i=0,current=start;i<size;i++,current--) {
1628 /* printf("%d\n",i);
1629 utf_display(c->name);*/
1630 use_class_as_object(c);
1631 tmpArray->data[i]=c;
1637 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end,classinfo **start) {
1638 #warning platform dependend
1640 classinfo **current;
1642 classinfo *privilegedAction;
1643 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1644 /* log_text("builtin_asm_getclassloader");
1645 printf("end %p, start %p, size %ld\n",end,start,size);*/
1647 if (!class_java_lang_SecurityManager)
1648 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1650 if (start==class_java_lang_SecurityManager) {
1656 privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1658 for(i=0,current=start;i<size;i++,current--) {
1660 if (c==privilegedAction) return NULL;
1661 if (c->classloader) return c->classloader;
1669 log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1670 init_systemclassloader();
1672 return SystemClassLoader;*/
1676 * These are local overrides for various environment variables in Emacs.
1677 * Please do not remove this and leave it at the end of the file, where
1678 * Emacs will automagically detect them.
1679 * ---------------------------------------------------------------------
1682 * indent-tabs-mode: t