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 1444 2004-11-05 13:54:52Z twisti $
49 #include "exceptions.h"
60 #include "toolbox/logging.h"
61 #include "toolbox/memory.h"
62 #include "threads/thread.h"
63 #include "threads/threadio.h"
64 #include "threads/locks.h"
65 #include "nat/java_lang_VMClass.h"
66 #include "nat/java_lang_Throwable.h"
68 /* Include files for IO functions */
72 #include <sys/types.h>
78 #include "threads/threadio.h"
80 /* include table of native functions */
82 #include "nativetable.inc"
85 /* for java-string to char conversion */
86 #define MAXSTRINGSIZE 1000
89 /******************** systemclasses required for native methods ***************/
91 classinfo *class_java_lang_Class;
92 classinfo *class_java_lang_VMClass;
93 classinfo *class_java_lang_System;
94 classinfo *class_java_lang_ClassLoader;
95 classinfo *class_gnu_java_lang_SystemClassLoader;
96 classinfo *class_java_lang_SecurityManager;
97 classinfo *class_java_lang_Double;
98 classinfo *class_java_lang_Float;
99 classinfo *class_java_lang_Long;
100 classinfo *class_java_lang_Byte;
101 classinfo *class_java_lang_Short;
102 classinfo *class_java_lang_Boolean;
103 classinfo *class_java_lang_Void;
104 classinfo *class_java_lang_Character;
105 classinfo *class_java_lang_Integer;
107 methodinfo *method_vmclass_init;
110 /* the system classloader object */
111 struct java_lang_ClassLoader *SystemClassLoader = NULL;
113 /* for raising exceptions from native methods */
114 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
115 java_objectheader* _exceptionptr = NULL;
118 /************* use classinfo structure as java.lang.Class object **************/
120 void use_class_as_object(classinfo *c)
122 if (!c->classvftbl) {
123 c->header.vftbl = class_java_lang_Class->vftbl;
124 c->classvftbl = true;
130 /*************************** include native methods ***************************/
133 #include "nat/GdkGraphics.c"
134 #include "nat/GtkComponentPeer.c"
135 #include "nat/GdkPixbufDecoder.c"
136 #include "nat/GtkScrollPanePeer.c"
137 #include "nat/GtkFileDialogPeer.c"
141 /************************** tables for methods ********************************/
146 #ifdef STATIC_CLASSPATH
147 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
149 /* table for fast string comparison */
150 static nativecompref nativecomptable[NATIVETABLESIZE];
152 /* string comparsion table initialized */
153 static bool nativecompdone = false;
156 /******************************************************************************/
158 #include "natcalls.h"
161 /*********************** function: native_loadclasses **************************
163 load classes required for native methods
165 *******************************************************************************/
167 void native_loadclasses()
169 static int classesLoaded = 0; /*temporary hack JoWenn*/
176 class_java_lang_Cloneable =
177 class_new(utf_new_char("java/lang/Cloneable"));
178 class_load(class_java_lang_Cloneable);
179 class_link(class_java_lang_Cloneable);
181 class_java_lang_Class =
182 class_new(utf_new_char("java/lang/Class"));
183 class_load(class_java_lang_Class);
184 class_link(class_java_lang_Class);
186 class_java_lang_VMClass =
187 class_new(utf_new_char("java/lang/VMClass"));
188 class_load(class_java_lang_VMClass);
189 class_link(class_java_lang_VMClass);
191 class_java_lang_ClassLoader =
192 class_new(utf_new_char("java/lang/ClassLoader"));
193 class_load(class_java_lang_ClassLoader);
194 class_link(class_java_lang_ClassLoader);
196 /* load classes for wrapping primitive types */
197 class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
198 class_load(class_java_lang_Double);
199 class_link(class_java_lang_Double);
201 class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
202 class_load(class_java_lang_Float);
203 class_link(class_java_lang_Float);
205 class_java_lang_Character = class_new(utf_new_char("java/lang/Character"));
206 class_load(class_java_lang_Character);
207 class_link(class_java_lang_Character);
209 class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
210 class_load(class_java_lang_Integer);
211 class_link(class_java_lang_Integer);
213 class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
214 class_load(class_java_lang_Long);
215 class_link(class_java_lang_Long);
217 class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
218 class_load(class_java_lang_Byte);
219 class_link(class_java_lang_Byte);
221 class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
222 class_load(class_java_lang_Short);
223 class_link(class_java_lang_Short);
225 class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
226 class_load(class_java_lang_Boolean);
227 class_link(class_java_lang_Boolean);
229 class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
230 class_load(class_java_lang_Void);
231 class_link(class_java_lang_Void);
236 /*****************************************************************************
238 create systemclassloader object and initialize instance fields
240 ******************************************************************************/
242 void init_systemclassloader()
244 log_text("init_systemclassloader");
245 if (!SystemClassLoader) {
246 native_loadclasses();
247 log_text("Initializing new system class loader");
248 /* create object and call initializer */
249 SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
251 /* systemclassloader has no parent */
252 SystemClassLoader->parent = NULL;
253 SystemClassLoader->initialized = true;
255 log_text("leaving system class loader");
259 /*********************** Function: native_findfunction *************************
261 Looks up a method (must have the same class name, method name, descriptor
262 and 'static'ness) and returns a function pointer to it.
263 Returns: function pointer or NULL (if there is no such method)
265 Remark: For faster operation, the names/descriptors are converted from C
266 strings to Unicode the first time this function is called.
268 *******************************************************************************/
270 functionptr native_findfunction(utf *cname, utf *mname,
271 utf *desc, bool isstatic)
273 #ifdef STATIC_CLASSPATH
275 /* entry of table for fast string comparison */
276 struct nativecompref *n;
277 /* for warning message if no function is found */
281 isstatic = isstatic ? true : false;
283 if (!nativecompdone) {
284 for (i = 0; i < NATIVETABLESIZE; i++) {
285 nativecomptable[i].classname =
286 utf_new_char(nativetable[i].classname);
287 nativecomptable[i].methodname =
288 utf_new_char(nativetable[i].methodname);
289 nativecomptable[i].descriptor =
290 utf_new_char(nativetable[i].descriptor);
291 nativecomptable[i].isstatic =
292 nativetable[i].isstatic;
293 nativecomptable[i].func =
296 nativecompdone = true;
301 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
303 buffer = MNEW(char, buffer_len);
305 strcpy(buffer, "searching matching function in native table:");
306 utf_sprint(buffer+strlen(buffer), mname);
307 strcpy(buffer+strlen(buffer), ": ");
308 utf_sprint(buffer+strlen(buffer), desc);
309 strcpy(buffer+strlen(buffer), " for class ");
310 utf_sprint(buffer+strlen(buffer), cname);
314 MFREE(buffer, char, buffer_len);
317 for (i = 0; i < NATIVETABLESIZE; i++) {
318 n = &(nativecomptable[i]);
320 if (cname == n->classname && mname == n->methodname &&
321 desc == n->descriptor && isstatic == n->isstatic)
325 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
329 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
331 buffer = MNEW(char, buffer_len);
333 strcpy(buffer, "comparing with:");
334 utf_sprint(buffer+strlen(buffer), n->methodname);
335 strcpy (buffer+strlen(buffer), ": ");
336 utf_sprint(buffer+strlen(buffer), n->descriptor);
337 strcpy(buffer+strlen(buffer), " for class ");
338 utf_sprint(buffer+strlen(buffer), n->classname);
342 MFREE(buffer, char, buffer_len);
349 /* no function was found, display warning */
352 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
354 buffer = MNEW(char, buffer_len);
356 strcpy(buffer, "warning: native function ");
357 utf_sprint(buffer + strlen(buffer), mname);
358 strcpy(buffer + strlen(buffer), ": ");
359 utf_sprint(buffer + strlen(buffer), desc);
360 strcpy(buffer + strlen(buffer), " not found in class ");
361 utf_sprint(buffer + strlen(buffer), cname);
365 MFREE(buffer, char, buffer_len);
369 /* keep compiler happy */
372 /* dynamic classpath */
378 /********************** function: javastring_new *******************************
380 creates a new object of type java/lang/String with the text of
381 the specified utf8-string
383 return: pointer to the string or NULL if memory is exhausted.
385 *******************************************************************************/
387 java_lang_String *javastring_new(utf *u)
389 char *utf_ptr; /* current utf character in utf string */
390 u4 utflength; /* length of utf-string if uncompressed */
391 java_lang_String *s; /* result-string */
396 *exceptionptr = new_nullpointerexception();
401 utflength = utf_strlen(u);
403 s = (java_lang_String *) builtin_new(class_java_lang_String);
404 a = builtin_newarray_char(utflength);
406 /* javastring or character-array could not be created */
410 /* decompress utf-string */
411 for (i = 0; i < utflength; i++)
412 a->data[i] = utf_nextu2(&utf_ptr);
414 /* set fields of the javastring-object */
417 s->count = utflength;
423 /********************** function: javastring_new_char **************************
425 creates a new java/lang/String object which contains the convertet
426 C-string passed via text.
428 return: the object pointer or NULL if memory is exhausted.
430 *******************************************************************************/
432 java_lang_String *javastring_new_char(char *text)
435 s4 len; /* length of the string */
436 java_lang_String *s; /* result-string */
440 *exceptionptr = new_nullpointerexception();
446 s = (java_lang_String *) builtin_new(class_java_lang_String);
447 a = builtin_newarray_char(len);
449 /* javastring or character-array could not be created */
454 for (i = 0; i < len; i++)
455 a->data[i] = text[i];
457 /* set fields of the javastring-object */
466 /************************* function javastring_tochar **************************
468 converts a Java string into a C string.
470 return: pointer to C string
472 Caution: every call of this function overwrites the previous string !!!
474 *******************************************************************************/
476 static char stringbuffer[MAXSTRINGSIZE];
478 char *javastring_tochar(java_objectheader *so)
480 java_lang_String *s = (java_lang_String *) so;
492 if (s->count > MAXSTRINGSIZE)
495 for (i = 0; i < s->count; i++)
496 stringbuffer[i] = a->data[s->offset + i];
498 stringbuffer[i] = '\0';
504 /****************** function class_findfield_approx ****************************
506 searches in 'classinfo'-structure for a field with the
509 *******************************************************************************/
511 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
515 for (i = 0; i < c->fieldscount; i++) {
516 /* compare field names */
517 if ((c->fields[i].name == name))
518 return &(c->fields[i]);
521 /* field was not found, raise exception */
522 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
528 s4 class_findfield_index_approx(classinfo *c, utf *name)
532 for (i = 0; i < c->fieldscount; i++) {
533 /* compare field names */
534 if ((c->fields[i].name == name))
538 /* field was not found, raise exception */
539 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
545 /********************** function: native_new_and_init *************************
547 Creates a new object on the heap and calls the initializer.
548 Returns the object pointer or NULL if memory is exhausted.
550 *******************************************************************************/
552 java_objectheader *native_new_and_init(classinfo *c)
555 java_objectheader *o;
558 return *exceptionptr;
560 o = builtin_new(c); /* create object */
565 /* find initializer */
567 m = class_findmethod(c,
568 utf_new_char("<init>"),
569 utf_new_char("()V"));
571 if (!m) { /* initializer not found */
573 char logtext[MAXLOGTEXT];
574 sprintf(logtext, "Warning: class has no instance-initializer: ");
575 utf_sprint_classname(logtext + strlen(logtext), c->name);
581 /* call initializer */
583 asm_calljavafunction(m, o, NULL, NULL, NULL);
589 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
592 java_objectheader *o;
595 return *exceptionptr;
597 o = builtin_new(c); /* create object */
602 /* find initializer */
604 m = class_findmethod(c,
605 utf_new_char("<init>"),
606 utf_new_char("(Ljava/lang/String;)V"));
608 if (!m) { /* initializer not found */
610 char logtext[MAXLOGTEXT];
611 sprintf(logtext, "Warning: class has no instance-initializer: ");
612 utf_sprint_classname(logtext + strlen(logtext), c->name);
618 /* call initializer */
620 asm_calljavafunction(m, o, s, NULL, NULL);
626 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
629 java_objectheader *o;
632 return *exceptionptr;
634 o = builtin_new(c); /* create object */
638 /* find initializer */
640 m = class_findmethod(c,
641 utf_new_char("<init>"),
642 utf_new_char("(I)V"));
644 if (!m) { /* initializer not found */
646 char logtext[MAXLOGTEXT];
647 sprintf(logtext, "Warning: class has no instance-initializer: ");
648 utf_sprint_classname(logtext + strlen(logtext), c->name);
654 /* call initializer */
656 #if defined(__I386__) || defined(__POWERPC__)
657 asm_calljavafunction(m, o, (void *) i, NULL, NULL);
659 asm_calljavafunction(m, o, (void *) (s8) i, NULL, NULL);
666 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
669 java_objectheader *o;
672 return *exceptionptr;
674 o = builtin_new(c); /* create object */
678 /* find initializer */
680 m = class_findmethod(c,
681 utf_new_char("<init>"),
682 utf_new_char("(Ljava/lang/Throwable;)V"));
684 if (!m) { /* initializer not found */
686 char logtext[MAXLOGTEXT];
687 sprintf(logtext, "Warning: class has no instance-initializer: ");
688 utf_sprint_classname(logtext + strlen(logtext), c->name);
694 /* call initializer */
696 asm_calljavafunction(m, o, t, NULL, NULL);
702 /******************** function: stringtable_update ****************************
704 traverses the javastring hashtable and sets the vftbl-entries of
705 javastrings which were temporarily set to NULL, because
706 java.lang.Object was not yet loaded
708 *******************************************************************************/
710 void stringtable_update ()
712 java_lang_String *js;
714 literalstring *s; /* hashtable entry */
717 for (i = 0; i < string_hash.size; i++) {
718 s = string_hash.ptr[i];
722 js = (java_lang_String *) s->string;
724 if (!js || !js->value)
725 /* error in hashtable found */
726 panic("invalid literalstring in hashtable");
730 if (!js->header.vftbl)
731 /* vftbl of javastring is NULL */
732 js->header.vftbl = class_java_lang_String->vftbl;
734 if (!a->header.objheader.vftbl)
735 /* vftbl of character-array is NULL */
736 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
738 /* follow link in external hash chain */
746 /************************* function: u2_utflength ***************************
748 returns the utf length in bytes of a u2 array
750 *****************************************************************************/
752 u4 u2_utflength(u2 *text, u4 u2_length)
754 u4 result_len = 0; /* utf length in bytes */
755 u2 ch; /* current unicode character */
758 for (len = 0; len < u2_length; len++) {
759 /* next unicode character */
762 /* determine bytes required to store unicode character as utf */
763 if (ch && (ch < 0x80))
775 /********************* function: utf_new_u2 ***********************************
777 make utf symbol from u2 array,
778 if isclassname is true '.' is replaced by '/'
780 *******************************************************************************/
782 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
784 char *buffer; /* memory buffer for unicode characters */
785 char *pos; /* pointer to current position in buffer */
786 u4 left; /* unicode characters left */
787 u4 buflength; /* utf length in bytes of the u2 array */
788 utf *result; /* resulting utf-string */
791 /* determine utf length in bytes and allocate memory */
792 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
793 buflength = u2_utflength(unicode_pos, unicode_length);
794 buffer = MNEW(char, buflength);
799 for (i = 0; i++ < unicode_length; unicode_pos++) {
800 /* next unicode character */
803 if ((c != 0) && (c < 0x80)) {
806 if ((int) left < 0) break;
807 /* convert classname */
808 if (isclassname && c == '.')
813 } else if (c < 0x800) {
815 unsigned char high = c >> 6;
816 unsigned char low = c & 0x3F;
818 if ((int) left < 0) break;
819 *pos++ = high | 0xC0;
825 char mid = (c >> 6) & 0x3F;
828 if ((int) left < 0) break;
829 *pos++ = high | 0xE0;
835 /* insert utf-string into symbol-table */
836 result = utf_new(buffer,buflength);
838 MFREE(buffer, char, buflength);
844 /********************* function: javastring_toutf *****************************
846 make utf symbol from javastring
848 *******************************************************************************/
850 utf *javastring_toutf(java_lang_String *string, bool isclassname)
852 java_lang_String *str = (java_lang_String *) string;
854 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
855 /* fflush(stdout); */
857 return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
861 /********************* function: literalstring_u2 *****************************
863 searches for the javastring with the specified u2-array in
864 the string hashtable, if there is no such string a new one is
867 if copymode is true a copy of the u2-array is made
869 *******************************************************************************/
871 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
874 literalstring *s; /* hashtable element */
875 java_lang_String *js; /* u2-array wrapped in javastring */
876 java_chararray *stringdata; /* copy of u2-array */
882 //#define DEBUG_LITERALSTRING_U2
883 #ifdef DEBUG_LITERALSTRING_U2
884 printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
888 /* find location in hashtable */
889 key = unicode_hashkey(a->data + offset, length);
890 slot = key & (string_hash.size - 1);
891 s = string_hash.ptr[slot];
894 js = (java_lang_String *) s->string;
896 if (length == js->count) {
898 for (i = 0; i < length; i++) {
899 if (a->data[offset + i] != js->value->data[i])
903 /* string already in hashtable, free memory */
905 mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
907 #ifdef DEBUG_LITERALSTRING_U2
908 printf("literalstring_u2: foundentry at %p\n", js);
909 utf_display(javastring_toutf(js, 0));
913 return (java_objectheader *) js;
917 /* follow link in external hash chain */
922 /* create copy of u2-array for new javastring */
923 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
924 stringdata = mem_alloc(arraysize);
925 /* memcpy(stringdata, a, arraysize); */
926 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
927 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
933 /* location in hashtable found, complete arrayheader */
934 stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
935 stringdata->header.size = length;
937 /* if we use eager loading, we have to check loaded String class */
939 class_java_lang_String =
940 class_new_intern(utf_new_char("java/lang/String"));
942 if (!class_load(class_java_lang_String))
945 list_addfirst(&unlinkedclasses, class_java_lang_String);
948 /* create new javastring */
949 js = NEW(java_lang_String);
950 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
951 initObjectLock(&js->header);
953 js->header.vftbl = class_java_lang_String->vftbl;
954 js->value = stringdata;
958 #ifdef DEBUG_LITERALSTRING_U2
959 printf("literalstring_u2: newly created at %p\n", js);
960 utf_display(javastring_toutf(js, 0));
965 /* create new literalstring */
966 s = NEW(literalstring);
967 s->hashlink = string_hash.ptr[slot];
968 s->string = (java_objectheader *) js;
969 string_hash.ptr[slot] = s;
971 /* update number of hashtable entries */
972 string_hash.entries++;
974 /* reorganization of hashtable */
975 if (string_hash.entries > (string_hash.size * 2)) {
976 /* reorganization of hashtable, average length of
977 the external chains is approx. 2 */
981 hashtable newhash; /* the new hashtable */
983 /* create new hashtable, double the size */
984 init_hashtable(&newhash, string_hash.size * 2);
985 newhash.entries = string_hash.entries;
987 /* transfer elements to new hashtable */
988 for (i = 0; i < string_hash.size; i++) {
989 s = string_hash.ptr[i];
991 literalstring *nexts = s->hashlink;
992 js = (java_lang_String *) s->string;
993 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
995 s->hashlink = newhash.ptr[slot];
996 newhash.ptr[slot] = s;
998 /* follow link in external hash chain */
1003 /* dispose old table */
1004 MFREE(string_hash.ptr, void*, string_hash.size);
1005 string_hash = newhash;
1008 return (java_objectheader *) js;
1012 /******************** Function: literalstring_new *****************************
1014 creates a new javastring with the text of the utf-symbol
1015 and inserts it into the string hashtable
1017 *******************************************************************************/
1019 java_objectheader *literalstring_new(utf *u)
1021 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1022 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1023 java_chararray *a; /* u2-array constructed from utf string */
1026 /* allocate memory */
1027 a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1029 /* convert utf-string to u2-array */
1030 for (i = 0; i < utflength; i++)
1031 a->data[i] = utf_nextu2(&utf_ptr);
1033 return literalstring_u2(a, utflength, 0, false);
1037 /********************** function: literalstring_free **************************
1039 removes a javastring from memory
1041 ******************************************************************************/
1043 void literalstring_free(java_objectheader* sobj)
1045 java_lang_String *s = (java_lang_String *) sobj;
1046 java_chararray *a = s->value;
1048 /* dispose memory of java.lang.String object */
1049 FREE(s, java_lang_String);
1051 /* dispose memory of java-characterarray */
1052 FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1056 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1060 /* XXX this kind of copying does not work (in the general
1061 * case). The interface tables would have to be copied, too. I
1062 * don't see why we should make a copy anyway. -Edwin
1064 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1065 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1066 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1071 /******************************************************************************************
1073 creates method signature (excluding return type) from array of
1074 class-objects representing the parameters of the method
1076 *******************************************************************************************/
1079 utf *create_methodsig(java_objectarray* types, char *retType)
1081 char *buffer; /* buffer for building the desciptor */
1082 char *pos; /* current position in buffer */
1083 utf *result; /* the method signature */
1084 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1087 if (!types) return NULL;
1089 /* determine required buffer-size */
1090 for (i = 0; i < types->header.size; i++) {
1091 classinfo *c = (classinfo *) types->data[i];
1092 buffer_size = buffer_size + c->name->blength + 2;
1095 if (retType) buffer_size += strlen(retType);
1097 /* allocate buffer */
1098 buffer = MNEW(u1, buffer_size);
1101 /* method-desciptor starts with parenthesis */
1104 for (i = 0; i < types->header.size; i++) {
1107 /* current argument */
1108 classinfo *c = (classinfo *) types->data[i];
1110 /* current position in utf-text */
1111 char *utf_ptr = c->name->text;
1113 /* determine type of argument */
1114 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1116 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1117 *pos++ = *utf_ptr; /* copy text */
1121 /* check for primitive types */
1122 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1123 char *utf_pos = utf_ptr - 1;
1124 char *primitive = primitivetype_table[j].wrapname;
1127 while (utf_pos < utf_end(c->name)) {
1128 if (*utf_pos++ != *primitive++) goto nomatch;
1131 /* primitive type found */
1132 *pos++ = primitivetype_table[j].typesig;
1139 /* no primitive type and no arrayclass, so must be object */
1143 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1157 for (i = 0; i < strlen(retType); i++) {
1158 *pos++ = retType[i];
1162 /* create utf-string */
1163 result = utf_new(buffer, (pos - buffer));
1164 MFREE(buffer, u1, buffer_size);
1170 /******************************************************************************************
1172 retrieve the next argument or returntype from a descriptor
1173 and return the corresponding class
1175 *******************************************************************************************/
1177 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1179 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1180 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1183 panic("illegal descriptor");
1185 if (skip) return NULL;
1187 use_class_as_object(c);
1192 /* get_parametertypes **********************************************************
1194 use the descriptor of a method to generate a java/lang/Class array
1195 which contains the classes of the parametertypes of the method
1197 *******************************************************************************/
1199 java_objectarray* get_parametertypes(methodinfo *m)
1201 utf *descr = m->descriptor; /* method-descriptor */
1202 char *utf_ptr = descr->text; /* current position in utf-text */
1203 char *desc_end = utf_end(descr); /* points behind utf string */
1204 java_objectarray* result;
1205 int parametercount = 0;
1209 utf_nextu2(&utf_ptr);
1211 /* determine number of parameters */
1212 while (*utf_ptr != ')') {
1213 get_type(&utf_ptr, desc_end, true);
1217 /* create class-array */
1218 result = builtin_anewarray(parametercount, class_java_lang_Class);
1220 utf_ptr = descr->text;
1221 utf_nextu2(&utf_ptr);
1223 /* get returntype classes */
1224 for (i = 0; i < parametercount; i++)
1226 (java_objectheader *) get_type(&utf_ptr, desc_end, false);
1232 /* get_exceptiontypes **********************************************************
1234 get the exceptions which can be thrown by a method
1236 *******************************************************************************/
1238 java_objectarray* get_exceptiontypes(methodinfo *m) {
1239 u2 exccount=m->thrownexceptionscount;
1241 java_objectarray *result;
1242 /* create class-array */
1243 result = builtin_anewarray(exccount, class_java_lang_Class);
1244 for (i=0;i<exccount;i++) {
1245 java_objectheader *oh=(java_objectheader*)(m->thrownexceptions[i]);
1246 use_class_as_object(oh);
1256 /******************************************************************************************
1258 get the returntype class of a method
1260 *******************************************************************************************/
1262 classinfo *get_returntype(methodinfo *m)
1264 char *utf_ptr; /* current position in utf-text */
1265 char *desc_end; /* points behind utf string */
1266 utf *desc = m->descriptor; /* method-descriptor */
1268 utf_ptr = desc->text;
1269 desc_end = utf_end(desc);
1271 /* ignore parametertypes */
1272 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1275 return get_type(&utf_ptr,desc_end, false);
1279 /*****************************************************************************/
1280 /*****************************************************************************/
1283 /*--------------------------------------------------------*/
1284 void printNativeCall(nativeCall nc) {
1287 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1288 for (i=0; i<nc.methCnt; i++) {
1289 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1291 for (j=0; j<nc.callCnt[i]; j++) {
1292 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1293 nc.methods[i].methodCalls[j].classname,
1294 nc.methods[i].methodCalls[j].methodname,
1295 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1298 printf("-+++++--------------------\n");fflush(stdout);
1301 /*--------------------------------------------------------*/
1302 void printCompNativeCall(nativeCompCall nc) {
1304 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1305 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1306 utf_display(nc.classname); fflush(stdout);
1308 for (i=0; i<nc.methCnt; i++) {
1309 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1310 utf_display(nc.methods[i].methodname); fflush(stdout);
1311 utf_display(nc.methods[i].descriptor);fflush(stdout);
1312 printf("\n");fflush(stdout);
1314 for (j=0; j<nc.callCnt[i]; j++) {
1315 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1316 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1317 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1318 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1319 printf("\n");fflush(stdout);
1322 printf("---------------------\n");fflush(stdout);
1326 /*--------------------------------------------------------*/
1327 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1340 /*--------------------------------------------------------*/
1341 nativeCall* findNativeClassCalls(char *aclassname ) {
1344 for (i=0;i<NATIVECALLSSIZE; i++) {
1345 /* convert table to utf later to speed up search */
1346 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1347 return &nativeCalls[i];
1352 /*--------------------------------------------------------*/
1353 /*--------------------------------------------------------*/
1354 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1358 ncc->classname = utf_new_char(nc.classname);
1359 ncc->methCnt = nc.methCnt;
1361 for (i=0; i<nc.methCnt; i++) {
1362 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1363 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1364 ncc->callCnt[i] = nc.callCnt[i];
1366 for (j=0; j<nc.callCnt[i]; j++) {
1368 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1370 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1371 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1372 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1375 ncc->methods[i].methodCalls[j].methodname = NULL;
1376 ncc->methods[i].methodCalls[j].descriptor = NULL;
1384 /*--------------------------------------------------------*/
1386 bool natcall2utf(bool natcallcompdone) {
1389 if (natcallcompdone)
1392 for (i=0;i<NATIVECALLSSIZE; i++) {
1393 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1399 /*--------------------------------------------------------*/
1402 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end,classinfo **start)
1404 #if defined(__GNUC__)
1405 #warning platform dependend
1407 java_objectarray *tmpArray;
1409 classinfo **current;
1411 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1412 /*printf("end %p, start %p, size %ld\n",end,start,size);*/
1413 if (!class_java_lang_Class)
1414 class_java_lang_Class = class_new(utf_new_char ("java/lang/Class"));
1415 if (!class_java_lang_SecurityManager)
1416 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1418 if (start==class_java_lang_SecurityManager) {
1423 tmpArray=builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1425 for(i=0,current=start;i<size;i++,current--) {
1427 /* printf("%d\n",i);
1428 utf_display(c->name);*/
1429 use_class_as_object(c);
1430 tmpArray->data[i]=c;
1436 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end,classinfo **start)
1438 #if defined(__GNUC__)
1439 #warning platform dependend
1442 classinfo **current;
1444 classinfo *privilegedAction;
1445 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1446 /* log_text("builtin_asm_getclassloader");
1447 printf("end %p, start %p, size %ld\n",end,start,size);*/
1449 if (!class_java_lang_SecurityManager)
1450 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1452 if (start==class_java_lang_SecurityManager) {
1458 privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1460 for(i=0,current=start;i<size;i++,current--) {
1462 if (c==privilegedAction) return NULL;
1463 if (c->classloader) return c->classloader;
1471 log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1472 init_systemclassloader();
1474 return SystemClassLoader;*/
1478 * These are local overrides for various environment variables in Emacs.
1479 * Please do not remove this and leave it at the end of the file, where
1480 * Emacs will automagically detect them.
1481 * ---------------------------------------------------------------------
1484 * indent-tabs-mode: t