1 /* native/native.c - table of native functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
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 1875 2005-01-21 09:37:33Z twisti $
48 /* Include files for IO functions */
52 #include <sys/types.h>
59 #include "mm/memory.h"
60 #include "native/jni.h"
61 #include "native/native.h"
62 #include "native/include/java_lang_Throwable.h"
63 #include "toolbox/logging.h"
64 #include "vm/builtin.h"
65 #include "vm/exceptions.h"
66 #include "vm/global.h"
67 #include "vm/loader.h"
68 #include "vm/options.h"
69 #include "vm/tables.h"
70 #include "vm/jit/asmpart.h"
71 #include "vm/jit/jit.h"
74 /* include table of native functions ******************************************/
78 #include "native/vm/GtkComponentPeer.c"
79 #include "native/vm/GtkScrollPanePeer.c"
80 #include "native/vm/GtkFileDialogPeer.c"
83 #include "nativetable.inc"
86 /* for java-string to char conversion */
87 #define MAXSTRINGSIZE 1000
90 /******************** systemclasses required for native methods ***************/
92 classinfo *class_java_lang_Class;
93 classinfo *class_java_lang_VMClass;
94 classinfo *class_java_lang_System;
95 classinfo *class_java_lang_ClassLoader;
96 classinfo *class_gnu_java_lang_SystemClassLoader;
97 classinfo *class_java_lang_SecurityManager;
98 classinfo *class_java_lang_Double;
99 classinfo *class_java_lang_Float;
100 classinfo *class_java_lang_Long;
101 classinfo *class_java_lang_Byte;
102 classinfo *class_java_lang_Short;
103 classinfo *class_java_lang_Boolean;
104 classinfo *class_java_lang_Void;
105 classinfo *class_java_lang_Character;
106 classinfo *class_java_lang_Integer;
108 methodinfo *method_vmclass_init;
111 /* the system classloader object */
112 struct java_lang_ClassLoader *SystemClassLoader = NULL;
114 /* for raising exceptions from native methods */
115 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
116 java_objectheader* _exceptionptr = NULL;
119 /************* use classinfo structure as java.lang.Class object **************/
121 void use_class_as_object(classinfo *c)
123 if (!c->classvftbl) {
124 /* is the class loaded */
127 panic("Class could not be loaded in use_class_as_object");
128 /* is the class linked */
131 panic("Class could not be linked in use_class_as_object");
133 /*if (class_java_lang_Class ==0) panic("java/lang/Class not loaded in use_class_as_object");
134 if (class_java_lang_Class->vftbl ==0) panic ("vftbl == 0 in use_class_as_object");*/
135 c->header.vftbl = class_java_lang_Class->vftbl;
136 c->classvftbl = true;
137 /*printf("use_class_as_object: %s\n",c->name->text);*/
143 /************************** tables for methods ********************************/
148 #ifdef STATIC_CLASSPATH
149 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
151 /* table for fast string comparison */
152 static nativecompref nativecomptable[NATIVETABLESIZE];
154 /* string comparsion table initialized */
155 static bool nativecompdone = false;
159 /* XXX don't define this in a header file!!! */
161 static struct nativeCall nativeCalls[] =
163 #include "nativecalls.inc"
166 #define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall))
168 struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE];
170 /******************************************************************************/
172 /**include "natcalls.h" **/
175 /*********************** function: native_loadclasses **************************
177 load classes required for native methods
179 *******************************************************************************/
181 void native_loadclasses()
183 static int classesLoaded = 0; /*temporary hack JoWenn*/
191 #if !defined(STATIC_CLASSPATH)
192 /* We need to access the dummy native table, not only to remove a warning */
193 /* but to be sure that the table is not optimized away (gcc does this */
195 p = &dummynativetable;
198 class_java_lang_Cloneable =
199 class_new(utf_new_char("java/lang/Cloneable"));
200 class_load(class_java_lang_Cloneable);
201 class_link(class_java_lang_Cloneable);
203 class_java_lang_Class =
204 class_new(utf_new_char("java/lang/Class"));
205 class_load(class_java_lang_Class);
206 class_link(class_java_lang_Class);
208 class_java_lang_VMClass =
209 class_new(utf_new_char("java/lang/VMClass"));
210 class_load(class_java_lang_VMClass);
211 class_link(class_java_lang_VMClass);
213 class_java_lang_ClassLoader =
214 class_new(utf_new_char("java/lang/ClassLoader"));
215 class_load(class_java_lang_ClassLoader);
216 class_link(class_java_lang_ClassLoader);
218 /* load classes for wrapping primitive types */
219 class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
220 class_load(class_java_lang_Double);
221 class_link(class_java_lang_Double);
223 class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
224 class_load(class_java_lang_Float);
225 class_link(class_java_lang_Float);
227 class_java_lang_Character = class_new(utf_new_char("java/lang/Character"));
228 class_load(class_java_lang_Character);
229 class_link(class_java_lang_Character);
231 class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
232 class_load(class_java_lang_Integer);
233 class_link(class_java_lang_Integer);
235 class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
236 class_load(class_java_lang_Long);
237 class_link(class_java_lang_Long);
239 class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
240 class_load(class_java_lang_Byte);
241 class_link(class_java_lang_Byte);
243 class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
244 class_load(class_java_lang_Short);
245 class_link(class_java_lang_Short);
247 class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
248 class_load(class_java_lang_Boolean);
249 class_link(class_java_lang_Boolean);
251 class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
252 class_load(class_java_lang_Void);
253 class_link(class_java_lang_Void);
257 /*****************************************************************************
259 create systemclassloader object and initialize instance fields
261 ******************************************************************************/
263 void init_systemclassloader()
265 if (!SystemClassLoader) {
266 native_loadclasses();
268 /* create object and call initializer */
269 SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
271 /* systemclassloader has no parent */
272 SystemClassLoader->parent = NULL;
273 SystemClassLoader->initialized = true;
278 /*********************** Function: native_findfunction *************************
280 Looks up a method (must have the same class name, method name, descriptor
281 and 'static'ness) and returns a function pointer to it.
282 Returns: function pointer or NULL (if there is no such method)
284 Remark: For faster operation, the names/descriptors are converted from C
285 strings to Unicode the first time this function is called.
287 *******************************************************************************/
289 functionptr native_findfunction(utf *cname, utf *mname,
290 utf *desc, bool isstatic)
292 #ifdef STATIC_CLASSPATH
294 /* entry of table for fast string comparison */
295 struct nativecompref *n;
296 /* for warning message if no function is found */
300 isstatic = isstatic ? true : false;
302 if (!nativecompdone) {
303 for (i = 0; i < NATIVETABLESIZE; i++) {
304 nativecomptable[i].classname =
305 utf_new_char(nativetable[i].classname);
306 nativecomptable[i].methodname =
307 utf_new_char(nativetable[i].methodname);
308 nativecomptable[i].descriptor =
309 utf_new_char(nativetable[i].descriptor);
310 nativecomptable[i].isstatic =
311 nativetable[i].isstatic;
312 nativecomptable[i].func =
315 nativecompdone = true;
320 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
322 buffer = MNEW(char, buffer_len);
324 strcpy(buffer, "searching matching function in native table:");
325 utf_sprint(buffer+strlen(buffer), mname);
326 strcpy(buffer+strlen(buffer), ": ");
327 utf_sprint(buffer+strlen(buffer), desc);
328 strcpy(buffer+strlen(buffer), " for class ");
329 utf_sprint(buffer+strlen(buffer), cname);
333 MFREE(buffer, char, buffer_len);
336 for (i = 0; i < NATIVETABLESIZE; i++) {
337 n = &(nativecomptable[i]);
339 if (cname == n->classname && mname == n->methodname &&
340 desc == n->descriptor && isstatic == n->isstatic)
344 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
348 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
350 buffer = MNEW(char, buffer_len);
352 strcpy(buffer, "comparing with:");
353 utf_sprint(buffer+strlen(buffer), n->methodname);
354 strcpy (buffer+strlen(buffer), ": ");
355 utf_sprint(buffer+strlen(buffer), n->descriptor);
356 strcpy(buffer+strlen(buffer), " for class ");
357 utf_sprint(buffer+strlen(buffer), n->classname);
361 MFREE(buffer, char, buffer_len);
368 /* no function was found, display warning */
371 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
373 buffer = MNEW(char, buffer_len);
375 strcpy(buffer, "warning: native function ");
376 utf_sprint(buffer + strlen(buffer), mname);
377 strcpy(buffer + strlen(buffer), ": ");
378 utf_sprint(buffer + strlen(buffer), desc);
379 strcpy(buffer + strlen(buffer), " not found in class ");
380 utf_sprint(buffer + strlen(buffer), cname);
384 MFREE(buffer, char, buffer_len);
388 /* keep compiler happy */
391 /* dynamic classpath */
397 /********************** function: javastring_new *******************************
399 creates a new object of type java/lang/String with the text of
400 the specified utf8-string
402 return: pointer to the string or NULL if memory is exhausted.
404 *******************************************************************************/
406 java_lang_String *javastring_new(utf *u)
408 char *utf_ptr; /* current utf character in utf string */
409 u4 utflength; /* length of utf-string if uncompressed */
410 java_lang_String *s; /* result-string */
415 *exceptionptr = new_nullpointerexception();
420 utflength = utf_strlen(u);
422 s = (java_lang_String *) builtin_new(class_java_lang_String);
423 a = builtin_newarray_char(utflength);
425 /* javastring or character-array could not be created */
429 /* decompress utf-string */
430 for (i = 0; i < utflength; i++)
431 a->data[i] = utf_nextu2(&utf_ptr);
433 /* set fields of the javastring-object */
436 s->count = utflength;
442 /********************** function: javastring_new_char **************************
444 creates a new java/lang/String object which contains the convertet
445 C-string passed via text.
447 return: the object pointer or NULL if memory is exhausted.
449 *******************************************************************************/
451 java_lang_String *javastring_new_char(const char *text)
454 s4 len; /* length of the string */
455 java_lang_String *s; /* result-string */
459 *exceptionptr = new_nullpointerexception();
465 s = (java_lang_String *) builtin_new(class_java_lang_String);
466 a = builtin_newarray_char(len);
468 /* javastring or character-array could not be created */
473 for (i = 0; i < len; i++)
474 a->data[i] = text[i];
476 /* set fields of the javastring-object */
485 /************************* function javastring_tochar **************************
487 converts a Java string into a C string.
489 return: pointer to C string
491 Caution: every call of this function overwrites the previous string !!!
493 *******************************************************************************/
495 static char stringbuffer[MAXSTRINGSIZE];
497 char *javastring_tochar(java_objectheader *so)
499 java_lang_String *s = (java_lang_String *) so;
511 if (s->count > MAXSTRINGSIZE)
514 for (i = 0; i < s->count; i++)
515 stringbuffer[i] = a->data[s->offset + i];
517 stringbuffer[i] = '\0';
523 /****************** function class_findfield_approx ****************************
525 searches in 'classinfo'-structure for a field with the
528 *******************************************************************************/
530 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
534 for (i = 0; i < c->fieldscount; i++) {
535 /* compare field names */
536 if ((c->fields[i].name == name))
537 return &(c->fields[i]);
540 /* field was not found, raise exception */
541 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
547 s4 class_findfield_index_approx(classinfo *c, utf *name)
551 for (i = 0; i < c->fieldscount; i++) {
552 /* compare field names */
553 if ((c->fields[i].name == name))
557 /* field was not found, raise exception */
558 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
564 /********************** function: native_new_and_init *************************
566 Creates a new object on the heap and calls the initializer.
567 Returns the object pointer or NULL if memory is exhausted.
569 *******************************************************************************/
571 java_objectheader *native_new_and_init(classinfo *c)
574 java_objectheader *o;
577 return *exceptionptr;
586 /* find initializer */
588 m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
590 /* initializer not found */
595 /* call initializer */
597 asm_calljavafunction(m, o, NULL, NULL, NULL);
603 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
606 java_objectheader *o;
609 return *exceptionptr;
618 /* find initializer */
620 m = class_resolveclassmethod(c,
621 utf_new_char("<init>"),
622 utf_new_char("(Ljava/lang/String;)V"),
626 /* initializer not found */
631 /* call initializer */
633 asm_calljavafunction(m, o, s, NULL, NULL);
639 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
642 java_objectheader *o;
645 return *exceptionptr;
654 /* find initializer */
656 m = class_resolveclassmethod(c,
657 utf_new_char("<init>"),
658 utf_new_char("(I)V"),
662 /* initializer not found */
666 /* call initializer */
668 asm_calljavafunction(m, o, (void *) (ptrint) i, NULL, NULL);
674 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
677 java_objectheader *o;
680 return *exceptionptr;
689 /* find initializer */
691 m = class_findmethod(c,
692 utf_new_char("<init>"),
693 utf_new_char("(Ljava/lang/Throwable;)V"));
695 /* initializer not found */
700 /* call initializer */
702 asm_calljavafunction(m, o, t, NULL, NULL);
708 /******************** function: stringtable_update ****************************
710 traverses the javastring hashtable and sets the vftbl-entries of
711 javastrings which were temporarily set to NULL, because
712 java.lang.Object was not yet loaded
714 *******************************************************************************/
716 void stringtable_update ()
718 java_lang_String *js;
720 literalstring *s; /* hashtable entry */
723 for (i = 0; i < string_hash.size; i++) {
724 s = string_hash.ptr[i];
728 js = (java_lang_String *) s->string;
730 if (!js || !js->value)
731 /* error in hashtable found */
732 panic("invalid literalstring in hashtable");
736 if (!js->header.vftbl)
737 /* vftbl of javastring is NULL */
738 js->header.vftbl = class_java_lang_String->vftbl;
740 if (!a->header.objheader.vftbl)
741 /* vftbl of character-array is NULL */
742 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
744 /* follow link in external hash chain */
752 /************************* function: u2_utflength ***************************
754 returns the utf length in bytes of a u2 array
756 *****************************************************************************/
758 u4 u2_utflength(u2 *text, u4 u2_length)
760 u4 result_len = 0; /* utf length in bytes */
761 u2 ch; /* current unicode character */
764 for (len = 0; len < u2_length; len++) {
765 /* next unicode character */
768 /* determine bytes required to store unicode character as utf */
769 if (ch && (ch < 0x80))
781 /********************* function: utf_new_u2 ***********************************
783 make utf symbol from u2 array,
784 if isclassname is true '.' is replaced by '/'
786 *******************************************************************************/
788 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
790 char *buffer; /* memory buffer for unicode characters */
791 char *pos; /* pointer to current position in buffer */
792 u4 left; /* unicode characters left */
793 u4 buflength; /* utf length in bytes of the u2 array */
794 utf *result; /* resulting utf-string */
797 /* determine utf length in bytes and allocate memory */
798 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
799 buflength = u2_utflength(unicode_pos, unicode_length);
800 buffer = MNEW(char, buflength);
805 for (i = 0; i++ < unicode_length; unicode_pos++) {
806 /* next unicode character */
809 if ((c != 0) && (c < 0x80)) {
812 if ((int) left < 0) break;
813 /* convert classname */
814 if (isclassname && c == '.')
819 } else if (c < 0x800) {
821 unsigned char high = c >> 6;
822 unsigned char low = c & 0x3F;
824 if ((int) left < 0) break;
825 *pos++ = high | 0xC0;
831 char mid = (c >> 6) & 0x3F;
834 if ((int) left < 0) break;
835 *pos++ = high | 0xE0;
841 /* insert utf-string into symbol-table */
842 result = utf_new(buffer,buflength);
844 MFREE(buffer, char, buflength);
850 /********************* function: javastring_toutf *****************************
852 make utf symbol from javastring
854 *******************************************************************************/
856 utf *javastring_toutf(java_lang_String *string, bool isclassname)
858 java_lang_String *str = (java_lang_String *) string;
860 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
861 /* fflush(stdout); */
863 return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
867 /********************* function: literalstring_u2 *****************************
869 searches for the javastring with the specified u2-array in
870 the string hashtable, if there is no such string a new one is
873 if copymode is true a copy of the u2-array is made
875 *******************************************************************************/
877 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
880 literalstring *s; /* hashtable element */
881 java_lang_String *js; /* u2-array wrapped in javastring */
882 java_chararray *stringdata; /* copy of u2-array */
887 /* #define DEBUG_LITERALSTRING_U2 */
888 #ifdef DEBUG_LITERALSTRING_U2
889 printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
893 /* find location in hashtable */
894 key = unicode_hashkey(a->data + offset, length);
895 slot = key & (string_hash.size - 1);
896 s = string_hash.ptr[slot];
899 js = (java_lang_String *) s->string;
901 if (length == js->count) {
903 for (i = 0; i < length; i++) {
904 if (a->data[offset + i] != js->value->data[i])
908 /* string already in hashtable, free memory */
910 mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
912 #ifdef DEBUG_LITERALSTRING_U2
913 printf("literalstring_u2: foundentry at %p\n", js);
914 utf_display(javastring_toutf(js, 0));
918 return (java_objectheader *) js;
922 /* follow link in external hash chain */
927 /* create copy of u2-array for new javastring */
928 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
929 stringdata = mem_alloc(arraysize);
930 /* memcpy(stringdata, a, arraysize); */
931 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
932 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
938 /* location in hashtable found, complete arrayheader */
939 stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
940 stringdata->header.size = length;
942 /* if we use eager loading, we have to check loaded String class */
944 class_java_lang_String =
945 class_new_intern(utf_new_char("java/lang/String"));
947 if (!class_load(class_java_lang_String))
950 list_addfirst(&unlinkedclasses, class_java_lang_String);
953 /* create new javastring */
954 js = NEW(java_lang_String);
955 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
956 initObjectLock(&js->header);
958 js->header.vftbl = class_java_lang_String->vftbl;
959 js->value = stringdata;
963 #ifdef DEBUG_LITERALSTRING_U2
964 printf("literalstring_u2: newly created at %p\n", js);
965 utf_display(javastring_toutf(js, 0));
970 /* create new literalstring */
971 s = NEW(literalstring);
972 s->hashlink = string_hash.ptr[slot];
973 s->string = (java_objectheader *) js;
974 string_hash.ptr[slot] = s;
976 /* update number of hashtable entries */
977 string_hash.entries++;
979 /* reorganization of hashtable */
980 if (string_hash.entries > (string_hash.size * 2)) {
981 /* reorganization of hashtable, average length of
982 the external chains is approx. 2 */
986 hashtable newhash; /* the new hashtable */
988 /* create new hashtable, double the size */
989 init_hashtable(&newhash, string_hash.size * 2);
990 newhash.entries = string_hash.entries;
992 /* transfer elements to new hashtable */
993 for (i = 0; i < string_hash.size; i++) {
994 s = string_hash.ptr[i];
996 literalstring *nexts = s->hashlink;
997 js = (java_lang_String *) s->string;
998 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
1000 s->hashlink = newhash.ptr[slot];
1001 newhash.ptr[slot] = s;
1003 /* follow link in external hash chain */
1008 /* dispose old table */
1009 MFREE(string_hash.ptr, void*, string_hash.size);
1010 string_hash = newhash;
1013 return (java_objectheader *) js;
1017 /******************** Function: literalstring_new *****************************
1019 creates a new javastring with the text of the utf-symbol
1020 and inserts it into the string hashtable
1022 *******************************************************************************/
1024 java_objectheader *literalstring_new(utf *u)
1026 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1027 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1028 java_chararray *a; /* u2-array constructed from utf string */
1031 /* allocate memory */
1032 a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1034 /* convert utf-string to u2-array */
1035 for (i = 0; i < utflength; i++)
1036 a->data[i] = utf_nextu2(&utf_ptr);
1038 return literalstring_u2(a, utflength, 0, false);
1042 /********************** function: literalstring_free **************************
1044 removes a javastring from memory
1046 ******************************************************************************/
1048 void literalstring_free(java_objectheader* sobj)
1050 java_lang_String *s = (java_lang_String *) sobj;
1051 java_chararray *a = s->value;
1053 /* dispose memory of java.lang.String object */
1054 FREE(s, java_lang_String);
1056 /* dispose memory of java-characterarray */
1057 FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1061 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1065 /* XXX this kind of copying does not work (in the general
1066 * case). The interface tables would have to be copied, too. I
1067 * don't see why we should make a copy anyway. -Edwin
1069 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1070 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1071 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1076 /******************************************************************************************
1078 creates method signature (excluding return type) from array of
1079 class-objects representing the parameters of the method
1081 *******************************************************************************************/
1084 utf *create_methodsig(java_objectarray* types, char *retType)
1086 char *buffer; /* buffer for building the desciptor */
1087 char *pos; /* current position in buffer */
1088 utf *result; /* the method signature */
1089 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1092 if (!types) return NULL;
1094 /* determine required buffer-size */
1095 for (i = 0; i < types->header.size; i++) {
1096 classinfo *c = (classinfo *) types->data[i];
1097 buffer_size = buffer_size + c->name->blength + 2;
1100 if (retType) buffer_size += strlen(retType);
1102 /* allocate buffer */
1103 buffer = MNEW(char, buffer_size);
1106 /* method-desciptor starts with parenthesis */
1109 for (i = 0; i < types->header.size; i++) {
1112 /* current argument */
1113 classinfo *c = (classinfo *) types->data[i];
1115 /* current position in utf-text */
1116 char *utf_ptr = c->name->text;
1118 /* determine type of argument */
1119 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1121 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1122 *pos++ = *utf_ptr; /* copy text */
1126 /* check for primitive types */
1127 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1128 char *utf_pos = utf_ptr - 1;
1129 char *primitive = primitivetype_table[j].wrapname;
1132 while (utf_pos < utf_end(c->name)) {
1133 if (*utf_pos++ != *primitive++) goto nomatch;
1136 /* primitive type found */
1137 *pos++ = primitivetype_table[j].typesig;
1144 /* no primitive type and no arrayclass, so must be object */
1148 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1162 for (i = 0; i < strlen(retType); i++) {
1163 *pos++ = retType[i];
1167 /* create utf-string */
1168 result = utf_new(buffer, (pos - buffer));
1169 MFREE(buffer, char, buffer_size);
1175 /******************************************************************************************
1177 retrieve the next argument or returntype from a descriptor
1178 and return the corresponding class
1180 *******************************************************************************************/
1182 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1184 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1185 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1188 panic("illegal descriptor");
1190 if (skip) return NULL;
1192 use_class_as_object(c);
1197 /* get_parametertypes **********************************************************
1199 use the descriptor of a method to generate a java/lang/Class array
1200 which contains the classes of the parametertypes of the method
1202 *******************************************************************************/
1204 java_objectarray* get_parametertypes(methodinfo *m)
1206 utf *descr = m->descriptor; /* method-descriptor */
1207 char *utf_ptr = descr->text; /* current position in utf-text */
1208 char *desc_end = utf_end(descr); /* points behind utf string */
1209 java_objectarray* result;
1210 int parametercount = 0;
1214 utf_nextu2(&utf_ptr);
1216 /* determine number of parameters */
1217 while (*utf_ptr != ')') {
1218 get_type(&utf_ptr, desc_end, true);
1222 /* create class-array */
1223 result = builtin_anewarray(parametercount, class_java_lang_Class);
1225 utf_ptr = descr->text;
1226 utf_nextu2(&utf_ptr);
1228 /* get returntype classes */
1229 for (i = 0; i < parametercount; i++)
1231 (java_objectheader *) get_type(&utf_ptr, desc_end, false);
1237 /* get_exceptiontypes **********************************************************
1239 get the exceptions which can be thrown by a method
1241 *******************************************************************************/
1243 java_objectarray* get_exceptiontypes(methodinfo *m)
1247 java_objectarray *result;
1249 excount = m->thrownexceptionscount;
1251 /* create class-array */
1252 result = builtin_anewarray(excount, class_java_lang_Class);
1254 for (i = 0; i < excount; i++) {
1255 java_objectheader *o = (java_objectheader *) (m->thrownexceptions[i]);
1256 use_class_as_object((classinfo *) o);
1257 result->data[i] = o;
1267 /******************************************************************************************
1269 get the returntype class of a method
1271 *******************************************************************************************/
1273 classinfo *get_returntype(methodinfo *m)
1275 char *utf_ptr; /* current position in utf-text */
1276 char *desc_end; /* points behind utf string */
1277 utf *desc = m->descriptor; /* method-descriptor */
1279 utf_ptr = desc->text;
1280 desc_end = utf_end(desc);
1282 /* ignore parametertypes */
1283 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1286 return get_type(&utf_ptr,desc_end, false);
1290 /*****************************************************************************/
1291 /*****************************************************************************/
1294 /*--------------------------------------------------------*/
1295 void printNativeCall(nativeCall nc) {
1298 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1299 for (i=0; i<nc.methCnt; i++) {
1300 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1302 for (j=0; j<nc.callCnt[i]; j++) {
1303 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1304 nc.methods[i].methodCalls[j].classname,
1305 nc.methods[i].methodCalls[j].methodname,
1306 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1309 printf("-+++++--------------------\n");fflush(stdout);
1312 /*--------------------------------------------------------*/
1313 void printCompNativeCall(nativeCompCall nc) {
1315 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1316 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1317 utf_display(nc.classname); fflush(stdout);
1319 for (i=0; i<nc.methCnt; i++) {
1320 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1321 utf_display(nc.methods[i].methodname); fflush(stdout);
1322 utf_display(nc.methods[i].descriptor);fflush(stdout);
1323 printf("\n");fflush(stdout);
1325 for (j=0; j<nc.callCnt[i]; j++) {
1326 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1327 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1328 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1329 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1330 printf("\n");fflush(stdout);
1333 printf("---------------------\n");fflush(stdout);
1337 /*--------------------------------------------------------*/
1338 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1351 /*--------------------------------------------------------*/
1352 nativeCall* findNativeClassCalls(char *aclassname ) {
1355 for (i=0;i<NATIVECALLSSIZE; i++) {
1356 /* convert table to utf later to speed up search */
1357 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1358 return &nativeCalls[i];
1363 /*--------------------------------------------------------*/
1364 /*--------------------------------------------------------*/
1365 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1369 ncc->classname = utf_new_char(nc.classname);
1370 ncc->methCnt = nc.methCnt;
1372 for (i=0; i<nc.methCnt; i++) {
1373 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1374 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1375 ncc->callCnt[i] = nc.callCnt[i];
1377 for (j=0; j<nc.callCnt[i]; j++) {
1379 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1381 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1382 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1383 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1386 ncc->methods[i].methodCalls[j].methodname = NULL;
1387 ncc->methods[i].methodCalls[j].descriptor = NULL;
1395 /*--------------------------------------------------------*/
1397 bool natcall2utf(bool natcallcompdone) {
1400 if (natcallcompdone)
1403 for (i=0;i<NATIVECALLSSIZE; i++) {
1404 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1410 /*--------------------------------------------------------*/
1413 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo **start)
1415 #if defined(__GNUC__)
1416 #warning platform dependend
1418 java_objectarray *tmpArray;
1420 classinfo **current;
1424 size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
1426 /*printf("end %p, start %p, size %ld\n",end,start,size);*/
1427 if (!class_java_lang_Class)
1428 class_java_lang_Class = class_new(utf_new_char("java/lang/Class"));
1430 if (!class_java_lang_SecurityManager)
1431 class_java_lang_SecurityManager =
1432 class_new(utf_new_char("java/lang/SecurityManager"));
1435 if (start == class_java_lang_SecurityManager) {
1442 builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1444 for(i = 0, current = start; i < size; i++, current--) {
1446 /* printf("%d\n",i);
1447 utf_display(c->name);*/
1448 use_class_as_object(c);
1449 tmpArray->data[i] = (java_objectheader *) c;
1456 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start)
1458 #if defined(__GNUC__)
1459 #warning platform dependend
1462 classinfo **current;
1464 classinfo *privilegedAction;
1467 size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
1469 /* log_text("builtin_asm_getclassloader");
1470 printf("end %p, start %p, size %ld\n",end,start,size);*/
1472 if (!class_java_lang_SecurityManager)
1473 class_java_lang_SecurityManager =
1474 class_new(utf_new_char("java/lang/SecurityManager"));
1477 if (start == class_java_lang_SecurityManager) {
1483 privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1485 for(i = 0, current = start; i < size; i++, current--) {
1488 if (c == privilegedAction)
1492 return (java_lang_ClassLoader *) c->classloader;
1498 log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1499 init_systemclassloader();
1501 return SystemClassLoader;*/
1506 * These are local overrides for various environment variables in Emacs.
1507 * Please do not remove this and leave it at the end of the file, where
1508 * Emacs will automagically detect them.
1509 * ---------------------------------------------------------------------
1512 * indent-tabs-mode: t