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 1739 2004-12-08 11:01:19Z motse $
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"
73 #include "threads/thread.h"
74 #include "threads/threadio.h"
75 #include "threads/locks.h"
79 /* include table of native functions ******************************************/
80 #include "nativetable.inc"
83 /* for java-string to char conversion */
84 #define MAXSTRINGSIZE 1000
87 /******************** systemclasses required for native methods ***************/
89 classinfo *class_java_lang_Class;
90 classinfo *class_java_lang_VMClass;
91 classinfo *class_java_lang_System;
92 classinfo *class_java_lang_ClassLoader;
93 classinfo *class_gnu_java_lang_SystemClassLoader;
94 classinfo *class_java_lang_SecurityManager;
95 classinfo *class_java_lang_Double;
96 classinfo *class_java_lang_Float;
97 classinfo *class_java_lang_Long;
98 classinfo *class_java_lang_Byte;
99 classinfo *class_java_lang_Short;
100 classinfo *class_java_lang_Boolean;
101 classinfo *class_java_lang_Void;
102 classinfo *class_java_lang_Character;
103 classinfo *class_java_lang_Integer;
105 methodinfo *method_vmclass_init;
108 /* the system classloader object */
109 struct java_lang_ClassLoader *SystemClassLoader = NULL;
111 /* for raising exceptions from native methods */
112 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
113 java_objectheader* _exceptionptr = NULL;
116 /************* use classinfo structure as java.lang.Class object **************/
118 void use_class_as_object(classinfo *c)
120 if (!c->classvftbl) {
121 c->header.vftbl = class_java_lang_Class->vftbl;
122 c->classvftbl = true;
128 /************************** tables for methods ********************************/
133 #ifdef STATIC_CLASSPATH
134 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
136 /* table for fast string comparison */
137 static nativecompref nativecomptable[NATIVETABLESIZE];
139 /* string comparsion table initialized */
140 static bool nativecompdone = false;
144 /* XXX don't define this in a header file!!! */
146 static struct nativeCall nativeCalls[] =
148 #include "nativecalls.inc"
151 #define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall))
153 struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE];
155 /******************************************************************************/
157 /**include "natcalls.h" **/
160 /*********************** function: native_loadclasses **************************
162 load classes required for native methods
164 *******************************************************************************/
166 void native_loadclasses()
168 static int classesLoaded = 0; /*temporary hack JoWenn*/
175 class_java_lang_Cloneable =
176 class_new(utf_new_char("java/lang/Cloneable"));
177 class_load(class_java_lang_Cloneable);
178 class_link(class_java_lang_Cloneable);
180 class_java_lang_Class =
181 class_new(utf_new_char("java/lang/Class"));
182 class_load(class_java_lang_Class);
183 class_link(class_java_lang_Class);
185 class_java_lang_VMClass =
186 class_new(utf_new_char("java/lang/VMClass"));
187 class_load(class_java_lang_VMClass);
188 class_link(class_java_lang_VMClass);
190 class_java_lang_ClassLoader =
191 class_new(utf_new_char("java/lang/ClassLoader"));
192 class_load(class_java_lang_ClassLoader);
193 class_link(class_java_lang_ClassLoader);
195 /* load classes for wrapping primitive types */
196 class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
197 class_load(class_java_lang_Double);
198 class_link(class_java_lang_Double);
200 class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
201 class_load(class_java_lang_Float);
202 class_link(class_java_lang_Float);
204 class_java_lang_Character = class_new(utf_new_char("java/lang/Character"));
205 class_load(class_java_lang_Character);
206 class_link(class_java_lang_Character);
208 class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
209 class_load(class_java_lang_Integer);
210 class_link(class_java_lang_Integer);
212 class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
213 class_load(class_java_lang_Long);
214 class_link(class_java_lang_Long);
216 class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
217 class_load(class_java_lang_Byte);
218 class_link(class_java_lang_Byte);
220 class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
221 class_load(class_java_lang_Short);
222 class_link(class_java_lang_Short);
224 class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
225 class_load(class_java_lang_Boolean);
226 class_link(class_java_lang_Boolean);
228 class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
229 class_load(class_java_lang_Void);
230 class_link(class_java_lang_Void);
235 /*****************************************************************************
237 create systemclassloader object and initialize instance fields
239 ******************************************************************************/
241 void init_systemclassloader()
243 log_text("init_systemclassloader");
244 if (!SystemClassLoader) {
245 native_loadclasses();
246 log_text("Initializing new system class loader");
247 /* create object and call initializer */
248 SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
250 /* systemclassloader has no parent */
251 SystemClassLoader->parent = NULL;
252 SystemClassLoader->initialized = true;
254 log_text("leaving system class loader");
258 /*********************** Function: native_findfunction *************************
260 Looks up a method (must have the same class name, method name, descriptor
261 and 'static'ness) and returns a function pointer to it.
262 Returns: function pointer or NULL (if there is no such method)
264 Remark: For faster operation, the names/descriptors are converted from C
265 strings to Unicode the first time this function is called.
267 *******************************************************************************/
269 functionptr native_findfunction(utf *cname, utf *mname,
270 utf *desc, bool isstatic)
272 #ifdef STATIC_CLASSPATH
274 /* entry of table for fast string comparison */
275 struct nativecompref *n;
276 /* for warning message if no function is found */
280 isstatic = isstatic ? true : false;
282 if (!nativecompdone) {
283 for (i = 0; i < NATIVETABLESIZE; i++) {
284 nativecomptable[i].classname =
285 utf_new_char(nativetable[i].classname);
286 nativecomptable[i].methodname =
287 utf_new_char(nativetable[i].methodname);
288 nativecomptable[i].descriptor =
289 utf_new_char(nativetable[i].descriptor);
290 nativecomptable[i].isstatic =
291 nativetable[i].isstatic;
292 nativecomptable[i].func =
295 nativecompdone = true;
300 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
302 buffer = MNEW(char, buffer_len);
304 strcpy(buffer, "searching matching function in native table:");
305 utf_sprint(buffer+strlen(buffer), mname);
306 strcpy(buffer+strlen(buffer), ": ");
307 utf_sprint(buffer+strlen(buffer), desc);
308 strcpy(buffer+strlen(buffer), " for class ");
309 utf_sprint(buffer+strlen(buffer), cname);
313 MFREE(buffer, char, buffer_len);
316 for (i = 0; i < NATIVETABLESIZE; i++) {
317 n = &(nativecomptable[i]);
319 if (cname == n->classname && mname == n->methodname &&
320 desc == n->descriptor && isstatic == n->isstatic)
324 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
328 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
330 buffer = MNEW(char, buffer_len);
332 strcpy(buffer, "comparing with:");
333 utf_sprint(buffer+strlen(buffer), n->methodname);
334 strcpy (buffer+strlen(buffer), ": ");
335 utf_sprint(buffer+strlen(buffer), n->descriptor);
336 strcpy(buffer+strlen(buffer), " for class ");
337 utf_sprint(buffer+strlen(buffer), n->classname);
341 MFREE(buffer, char, buffer_len);
348 /* no function was found, display warning */
351 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
353 buffer = MNEW(char, buffer_len);
355 strcpy(buffer, "warning: native function ");
356 utf_sprint(buffer + strlen(buffer), mname);
357 strcpy(buffer + strlen(buffer), ": ");
358 utf_sprint(buffer + strlen(buffer), desc);
359 strcpy(buffer + strlen(buffer), " not found in class ");
360 utf_sprint(buffer + strlen(buffer), cname);
364 MFREE(buffer, char, buffer_len);
368 /* keep compiler happy */
371 /* dynamic classpath */
377 /********************** function: javastring_new *******************************
379 creates a new object of type java/lang/String with the text of
380 the specified utf8-string
382 return: pointer to the string or NULL if memory is exhausted.
384 *******************************************************************************/
386 java_lang_String *javastring_new(utf *u)
388 char *utf_ptr; /* current utf character in utf string */
389 u4 utflength; /* length of utf-string if uncompressed */
390 java_lang_String *s; /* result-string */
395 *exceptionptr = new_nullpointerexception();
400 utflength = utf_strlen(u);
402 s = (java_lang_String *) builtin_new(class_java_lang_String);
403 a = builtin_newarray_char(utflength);
405 /* javastring or character-array could not be created */
409 /* decompress utf-string */
410 for (i = 0; i < utflength; i++)
411 a->data[i] = utf_nextu2(&utf_ptr);
413 /* set fields of the javastring-object */
416 s->count = utflength;
422 /********************** function: javastring_new_char **************************
424 creates a new java/lang/String object which contains the convertet
425 C-string passed via text.
427 return: the object pointer or NULL if memory is exhausted.
429 *******************************************************************************/
431 java_lang_String *javastring_new_char(char *text)
434 s4 len; /* length of the string */
435 java_lang_String *s; /* result-string */
439 *exceptionptr = new_nullpointerexception();
445 s = (java_lang_String *) builtin_new(class_java_lang_String);
446 a = builtin_newarray_char(len);
448 /* javastring or character-array could not be created */
453 for (i = 0; i < len; i++)
454 a->data[i] = text[i];
456 /* set fields of the javastring-object */
465 /************************* function javastring_tochar **************************
467 converts a Java string into a C string.
469 return: pointer to C string
471 Caution: every call of this function overwrites the previous string !!!
473 *******************************************************************************/
475 static char stringbuffer[MAXSTRINGSIZE];
477 char *javastring_tochar(java_objectheader *so)
479 java_lang_String *s = (java_lang_String *) so;
491 if (s->count > MAXSTRINGSIZE)
494 for (i = 0; i < s->count; i++)
495 stringbuffer[i] = a->data[s->offset + i];
497 stringbuffer[i] = '\0';
503 /****************** function class_findfield_approx ****************************
505 searches in 'classinfo'-structure for a field with the
508 *******************************************************************************/
510 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
514 for (i = 0; i < c->fieldscount; i++) {
515 /* compare field names */
516 if ((c->fields[i].name == name))
517 return &(c->fields[i]);
520 /* field was not found, raise exception */
521 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
527 s4 class_findfield_index_approx(classinfo *c, utf *name)
531 for (i = 0; i < c->fieldscount; i++) {
532 /* compare field names */
533 if ((c->fields[i].name == name))
537 /* field was not found, raise exception */
538 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
544 /********************** function: native_new_and_init *************************
546 Creates a new object on the heap and calls the initializer.
547 Returns the object pointer or NULL if memory is exhausted.
549 *******************************************************************************/
551 java_objectheader *native_new_and_init(classinfo *c)
554 java_objectheader *o;
557 return *exceptionptr;
559 o = builtin_new(c); /* create object */
564 /* find initializer */
566 m = class_findmethod(c,
567 utf_new_char("<init>"),
568 utf_new_char("()V"));
570 if (!m) { /* initializer not found */
572 char logtext[MAXLOGTEXT];
573 sprintf(logtext, "Warning: class has no instance-initializer: ");
574 utf_sprint_classname(logtext + strlen(logtext), c->name);
580 /* call initializer */
582 asm_calljavafunction(m, o, NULL, NULL, NULL);
588 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
591 java_objectheader *o;
594 return *exceptionptr;
596 o = builtin_new(c); /* create object */
601 /* find initializer */
603 m = class_findmethod(c,
604 utf_new_char("<init>"),
605 utf_new_char("(Ljava/lang/String;)V"));
607 if (!m) { /* initializer not found */
609 char logtext[MAXLOGTEXT];
610 sprintf(logtext, "Warning: class has no instance-initializer: ");
611 utf_sprint_classname(logtext + strlen(logtext), c->name);
617 /* call initializer */
619 asm_calljavafunction(m, o, s, NULL, NULL);
625 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
628 java_objectheader *o;
631 return *exceptionptr;
633 o = builtin_new(c); /* create object */
637 /* find initializer */
639 m = class_findmethod(c,
640 utf_new_char("<init>"),
641 utf_new_char("(I)V"));
643 if (!m) { /* initializer not found */
645 char logtext[MAXLOGTEXT];
646 sprintf(logtext, "Warning: class has no instance-initializer: ");
647 utf_sprint_classname(logtext + strlen(logtext), c->name);
653 /* call initializer */
655 #if defined(__I386__) || defined(__POWERPC__)
656 asm_calljavafunction(m, o, (void *) i, NULL, NULL);
658 asm_calljavafunction(m, o, (void *) (s8) i, NULL, NULL);
665 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
668 java_objectheader *o;
671 return *exceptionptr;
673 o = builtin_new(c); /* create object */
677 /* find initializer */
679 m = class_findmethod(c,
680 utf_new_char("<init>"),
681 utf_new_char("(Ljava/lang/Throwable;)V"));
683 if (!m) { /* initializer not found */
685 char logtext[MAXLOGTEXT];
686 sprintf(logtext, "Warning: class has no instance-initializer: ");
687 utf_sprint_classname(logtext + strlen(logtext), c->name);
693 /* call initializer */
695 asm_calljavafunction(m, o, t, NULL, NULL);
701 /******************** function: stringtable_update ****************************
703 traverses the javastring hashtable and sets the vftbl-entries of
704 javastrings which were temporarily set to NULL, because
705 java.lang.Object was not yet loaded
707 *******************************************************************************/
709 void stringtable_update ()
711 java_lang_String *js;
713 literalstring *s; /* hashtable entry */
716 for (i = 0; i < string_hash.size; i++) {
717 s = string_hash.ptr[i];
721 js = (java_lang_String *) s->string;
723 if (!js || !js->value)
724 /* error in hashtable found */
725 panic("invalid literalstring in hashtable");
729 if (!js->header.vftbl)
730 /* vftbl of javastring is NULL */
731 js->header.vftbl = class_java_lang_String->vftbl;
733 if (!a->header.objheader.vftbl)
734 /* vftbl of character-array is NULL */
735 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
737 /* follow link in external hash chain */
745 /************************* function: u2_utflength ***************************
747 returns the utf length in bytes of a u2 array
749 *****************************************************************************/
751 u4 u2_utflength(u2 *text, u4 u2_length)
753 u4 result_len = 0; /* utf length in bytes */
754 u2 ch; /* current unicode character */
757 for (len = 0; len < u2_length; len++) {
758 /* next unicode character */
761 /* determine bytes required to store unicode character as utf */
762 if (ch && (ch < 0x80))
774 /********************* function: utf_new_u2 ***********************************
776 make utf symbol from u2 array,
777 if isclassname is true '.' is replaced by '/'
779 *******************************************************************************/
781 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
783 char *buffer; /* memory buffer for unicode characters */
784 char *pos; /* pointer to current position in buffer */
785 u4 left; /* unicode characters left */
786 u4 buflength; /* utf length in bytes of the u2 array */
787 utf *result; /* resulting utf-string */
790 /* determine utf length in bytes and allocate memory */
791 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
792 buflength = u2_utflength(unicode_pos, unicode_length);
793 buffer = MNEW(char, buflength);
798 for (i = 0; i++ < unicode_length; unicode_pos++) {
799 /* next unicode character */
802 if ((c != 0) && (c < 0x80)) {
805 if ((int) left < 0) break;
806 /* convert classname */
807 if (isclassname && c == '.')
812 } else if (c < 0x800) {
814 unsigned char high = c >> 6;
815 unsigned char low = c & 0x3F;
817 if ((int) left < 0) break;
818 *pos++ = high | 0xC0;
824 char mid = (c >> 6) & 0x3F;
827 if ((int) left < 0) break;
828 *pos++ = high | 0xE0;
834 /* insert utf-string into symbol-table */
835 result = utf_new(buffer,buflength);
837 MFREE(buffer, char, buflength);
843 /********************* function: javastring_toutf *****************************
845 make utf symbol from javastring
847 *******************************************************************************/
849 utf *javastring_toutf(java_lang_String *string, bool isclassname)
851 java_lang_String *str = (java_lang_String *) string;
853 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
854 /* fflush(stdout); */
856 return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
860 /********************* function: literalstring_u2 *****************************
862 searches for the javastring with the specified u2-array in
863 the string hashtable, if there is no such string a new one is
866 if copymode is true a copy of the u2-array is made
868 *******************************************************************************/
870 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
873 literalstring *s; /* hashtable element */
874 java_lang_String *js; /* u2-array wrapped in javastring */
875 java_chararray *stringdata; /* copy of u2-array */
880 /* #define DEBUG_LITERALSTRING_U2 */
881 #ifdef DEBUG_LITERALSTRING_U2
882 printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
886 /* find location in hashtable */
887 key = unicode_hashkey(a->data + offset, length);
888 slot = key & (string_hash.size - 1);
889 s = string_hash.ptr[slot];
892 js = (java_lang_String *) s->string;
894 if (length == js->count) {
896 for (i = 0; i < length; i++) {
897 if (a->data[offset + i] != js->value->data[i])
901 /* string already in hashtable, free memory */
903 mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
905 #ifdef DEBUG_LITERALSTRING_U2
906 printf("literalstring_u2: foundentry at %p\n", js);
907 utf_display(javastring_toutf(js, 0));
911 return (java_objectheader *) js;
915 /* follow link in external hash chain */
920 /* create copy of u2-array for new javastring */
921 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
922 stringdata = mem_alloc(arraysize);
923 /* memcpy(stringdata, a, arraysize); */
924 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
925 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
931 /* location in hashtable found, complete arrayheader */
932 stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
933 stringdata->header.size = length;
935 /* if we use eager loading, we have to check loaded String class */
937 class_java_lang_String =
938 class_new_intern(utf_new_char("java/lang/String"));
940 if (!class_load(class_java_lang_String))
943 list_addfirst(&unlinkedclasses, class_java_lang_String);
946 /* create new javastring */
947 js = NEW(java_lang_String);
948 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
949 initObjectLock(&js->header);
951 js->header.vftbl = class_java_lang_String->vftbl;
952 js->value = stringdata;
956 #ifdef DEBUG_LITERALSTRING_U2
957 printf("literalstring_u2: newly created at %p\n", js);
958 utf_display(javastring_toutf(js, 0));
963 /* create new literalstring */
964 s = NEW(literalstring);
965 s->hashlink = string_hash.ptr[slot];
966 s->string = (java_objectheader *) js;
967 string_hash.ptr[slot] = s;
969 /* update number of hashtable entries */
970 string_hash.entries++;
972 /* reorganization of hashtable */
973 if (string_hash.entries > (string_hash.size * 2)) {
974 /* reorganization of hashtable, average length of
975 the external chains is approx. 2 */
979 hashtable newhash; /* the new hashtable */
981 /* create new hashtable, double the size */
982 init_hashtable(&newhash, string_hash.size * 2);
983 newhash.entries = string_hash.entries;
985 /* transfer elements to new hashtable */
986 for (i = 0; i < string_hash.size; i++) {
987 s = string_hash.ptr[i];
989 literalstring *nexts = s->hashlink;
990 js = (java_lang_String *) s->string;
991 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
993 s->hashlink = newhash.ptr[slot];
994 newhash.ptr[slot] = s;
996 /* follow link in external hash chain */
1001 /* dispose old table */
1002 MFREE(string_hash.ptr, void*, string_hash.size);
1003 string_hash = newhash;
1006 return (java_objectheader *) js;
1010 /******************** Function: literalstring_new *****************************
1012 creates a new javastring with the text of the utf-symbol
1013 and inserts it into the string hashtable
1015 *******************************************************************************/
1017 java_objectheader *literalstring_new(utf *u)
1019 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1020 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1021 java_chararray *a; /* u2-array constructed from utf string */
1024 /* allocate memory */
1025 a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1027 /* convert utf-string to u2-array */
1028 for (i = 0; i < utflength; i++)
1029 a->data[i] = utf_nextu2(&utf_ptr);
1031 return literalstring_u2(a, utflength, 0, false);
1035 /********************** function: literalstring_free **************************
1037 removes a javastring from memory
1039 ******************************************************************************/
1041 void literalstring_free(java_objectheader* sobj)
1043 java_lang_String *s = (java_lang_String *) sobj;
1044 java_chararray *a = s->value;
1046 /* dispose memory of java.lang.String object */
1047 FREE(s, java_lang_String);
1049 /* dispose memory of java-characterarray */
1050 FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1054 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1058 /* XXX this kind of copying does not work (in the general
1059 * case). The interface tables would have to be copied, too. I
1060 * don't see why we should make a copy anyway. -Edwin
1062 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1063 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1064 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1069 /******************************************************************************************
1071 creates method signature (excluding return type) from array of
1072 class-objects representing the parameters of the method
1074 *******************************************************************************************/
1077 utf *create_methodsig(java_objectarray* types, char *retType)
1079 char *buffer; /* buffer for building the desciptor */
1080 char *pos; /* current position in buffer */
1081 utf *result; /* the method signature */
1082 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1085 if (!types) return NULL;
1087 /* determine required buffer-size */
1088 for (i = 0; i < types->header.size; i++) {
1089 classinfo *c = (classinfo *) types->data[i];
1090 buffer_size = buffer_size + c->name->blength + 2;
1093 if (retType) buffer_size += strlen(retType);
1095 /* allocate buffer */
1096 buffer = MNEW(char, buffer_size);
1099 /* method-desciptor starts with parenthesis */
1102 for (i = 0; i < types->header.size; i++) {
1105 /* current argument */
1106 classinfo *c = (classinfo *) types->data[i];
1108 /* current position in utf-text */
1109 char *utf_ptr = c->name->text;
1111 /* determine type of argument */
1112 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1114 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1115 *pos++ = *utf_ptr; /* copy text */
1119 /* check for primitive types */
1120 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1121 char *utf_pos = utf_ptr - 1;
1122 char *primitive = primitivetype_table[j].wrapname;
1125 while (utf_pos < utf_end(c->name)) {
1126 if (*utf_pos++ != *primitive++) goto nomatch;
1129 /* primitive type found */
1130 *pos++ = primitivetype_table[j].typesig;
1137 /* no primitive type and no arrayclass, so must be object */
1141 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1155 for (i = 0; i < strlen(retType); i++) {
1156 *pos++ = retType[i];
1160 /* create utf-string */
1161 result = utf_new(buffer, (pos - buffer));
1162 MFREE(buffer, char, buffer_size);
1168 /******************************************************************************************
1170 retrieve the next argument or returntype from a descriptor
1171 and return the corresponding class
1173 *******************************************************************************************/
1175 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1177 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1178 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1181 panic("illegal descriptor");
1183 if (skip) return NULL;
1185 use_class_as_object(c);
1190 /* get_parametertypes **********************************************************
1192 use the descriptor of a method to generate a java/lang/Class array
1193 which contains the classes of the parametertypes of the method
1195 *******************************************************************************/
1197 java_objectarray* get_parametertypes(methodinfo *m)
1199 utf *descr = m->descriptor; /* method-descriptor */
1200 char *utf_ptr = descr->text; /* current position in utf-text */
1201 char *desc_end = utf_end(descr); /* points behind utf string */
1202 java_objectarray* result;
1203 int parametercount = 0;
1207 utf_nextu2(&utf_ptr);
1209 /* determine number of parameters */
1210 while (*utf_ptr != ')') {
1211 get_type(&utf_ptr, desc_end, true);
1215 /* create class-array */
1216 result = builtin_anewarray(parametercount, class_java_lang_Class);
1218 utf_ptr = descr->text;
1219 utf_nextu2(&utf_ptr);
1221 /* get returntype classes */
1222 for (i = 0; i < parametercount; i++)
1224 (java_objectheader *) get_type(&utf_ptr, desc_end, false);
1230 /* get_exceptiontypes **********************************************************
1232 get the exceptions which can be thrown by a method
1234 *******************************************************************************/
1236 java_objectarray* get_exceptiontypes(methodinfo *m)
1240 java_objectarray *result;
1242 excount = m->thrownexceptionscount;
1244 /* create class-array */
1245 result = builtin_anewarray(excount, class_java_lang_Class);
1247 for (i = 0; i < excount; i++) {
1248 java_objectheader *o = (java_objectheader *) (m->thrownexceptions[i]);
1249 use_class_as_object((classinfo *) o);
1250 result->data[i] = o;
1260 /******************************************************************************************
1262 get the returntype class of a method
1264 *******************************************************************************************/
1266 classinfo *get_returntype(methodinfo *m)
1268 char *utf_ptr; /* current position in utf-text */
1269 char *desc_end; /* points behind utf string */
1270 utf *desc = m->descriptor; /* method-descriptor */
1272 utf_ptr = desc->text;
1273 desc_end = utf_end(desc);
1275 /* ignore parametertypes */
1276 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1279 return get_type(&utf_ptr,desc_end, false);
1283 /*****************************************************************************/
1284 /*****************************************************************************/
1287 /*--------------------------------------------------------*/
1288 void printNativeCall(nativeCall nc) {
1291 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1292 for (i=0; i<nc.methCnt; i++) {
1293 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1295 for (j=0; j<nc.callCnt[i]; j++) {
1296 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1297 nc.methods[i].methodCalls[j].classname,
1298 nc.methods[i].methodCalls[j].methodname,
1299 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1302 printf("-+++++--------------------\n");fflush(stdout);
1305 /*--------------------------------------------------------*/
1306 void printCompNativeCall(nativeCompCall nc) {
1308 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1309 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1310 utf_display(nc.classname); fflush(stdout);
1312 for (i=0; i<nc.methCnt; i++) {
1313 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1314 utf_display(nc.methods[i].methodname); fflush(stdout);
1315 utf_display(nc.methods[i].descriptor);fflush(stdout);
1316 printf("\n");fflush(stdout);
1318 for (j=0; j<nc.callCnt[i]; j++) {
1319 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1320 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1321 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1322 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1323 printf("\n");fflush(stdout);
1326 printf("---------------------\n");fflush(stdout);
1330 /*--------------------------------------------------------*/
1331 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1344 /*--------------------------------------------------------*/
1345 nativeCall* findNativeClassCalls(char *aclassname ) {
1348 for (i=0;i<NATIVECALLSSIZE; i++) {
1349 /* convert table to utf later to speed up search */
1350 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1351 return &nativeCalls[i];
1356 /*--------------------------------------------------------*/
1357 /*--------------------------------------------------------*/
1358 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1362 ncc->classname = utf_new_char(nc.classname);
1363 ncc->methCnt = nc.methCnt;
1365 for (i=0; i<nc.methCnt; i++) {
1366 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1367 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1368 ncc->callCnt[i] = nc.callCnt[i];
1370 for (j=0; j<nc.callCnt[i]; j++) {
1372 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1374 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1375 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1376 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1379 ncc->methods[i].methodCalls[j].methodname = NULL;
1380 ncc->methods[i].methodCalls[j].descriptor = NULL;
1388 /*--------------------------------------------------------*/
1390 bool natcall2utf(bool natcallcompdone) {
1393 if (natcallcompdone)
1396 for (i=0;i<NATIVECALLSSIZE; i++) {
1397 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1403 /*--------------------------------------------------------*/
1406 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo **start)
1408 #if defined(__GNUC__)
1409 #warning platform dependend
1411 java_objectarray *tmpArray;
1413 classinfo **current;
1417 size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
1419 /*printf("end %p, start %p, size %ld\n",end,start,size);*/
1420 if (!class_java_lang_Class)
1421 class_java_lang_Class = class_new(utf_new_char("java/lang/Class"));
1423 if (!class_java_lang_SecurityManager)
1424 class_java_lang_SecurityManager =
1425 class_new(utf_new_char("java/lang/SecurityManager"));
1428 if (start == class_java_lang_SecurityManager) {
1435 builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1437 for(i = 0, current = start; i < size; i++, current--) {
1439 /* printf("%d\n",i);
1440 utf_display(c->name);*/
1441 use_class_as_object(c);
1442 tmpArray->data[i] = (java_objectheader *) c;
1449 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start)
1451 #if defined(__GNUC__)
1452 #warning platform dependend
1455 classinfo **current;
1457 classinfo *privilegedAction;
1460 size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
1462 /* log_text("builtin_asm_getclassloader");
1463 printf("end %p, start %p, size %ld\n",end,start,size);*/
1465 if (!class_java_lang_SecurityManager)
1466 class_java_lang_SecurityManager =
1467 class_new(utf_new_char("java/lang/SecurityManager"));
1470 if (start == class_java_lang_SecurityManager) {
1476 privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1478 for(i = 0, current = start; i < size; i++, current--) {
1481 if (c == privilegedAction)
1485 return (java_lang_ClassLoader *) c->classloader;
1491 log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1492 init_systemclassloader();
1494 return SystemClassLoader;*/
1499 * These are local overrides for various environment variables in Emacs.
1500 * Please do not remove this and leave it at the end of the file, where
1501 * Emacs will automagically detect them.
1502 * ---------------------------------------------------------------------
1505 * indent-tabs-mode: t