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 1383 2004-08-02 07:27:00Z stefan $
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 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
148 /* table for fast string comparison */
149 static nativecompref nativecomptable[NATIVETABLESIZE];
151 /* string comparsion table initialized */
152 static bool nativecompdone = false;
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)
273 /* entry of table for fast string comparison */
274 struct nativecompref *n;
275 /* for warning message if no function is found */
279 isstatic = isstatic ? true : false;
281 if (!nativecompdone) {
282 for (i = 0; i < NATIVETABLESIZE; i++) {
283 nativecomptable[i].classname =
284 utf_new_char(nativetable[i].classname);
285 nativecomptable[i].methodname =
286 utf_new_char(nativetable[i].methodname);
287 nativecomptable[i].descriptor =
288 utf_new_char(nativetable[i].descriptor);
289 nativecomptable[i].isstatic =
290 nativetable[i].isstatic;
291 nativecomptable[i].func =
294 nativecompdone = true;
299 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
301 buffer = MNEW(char, buffer_len);
303 strcpy(buffer, "searching matching function in native table:");
304 utf_sprint(buffer+strlen(buffer), mname);
305 strcpy(buffer+strlen(buffer), ": ");
306 utf_sprint(buffer+strlen(buffer), desc);
307 strcpy(buffer+strlen(buffer), " for class ");
308 utf_sprint(buffer+strlen(buffer), cname);
312 MFREE(buffer, char, buffer_len);
315 for (i = 0; i < NATIVETABLESIZE; i++) {
316 n = &(nativecomptable[i]);
318 if (cname == n->classname && mname == n->methodname &&
319 desc == n->descriptor && isstatic == n->isstatic)
323 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
327 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
329 buffer = MNEW(char, buffer_len);
331 strcpy(buffer, "comparing with:");
332 utf_sprint(buffer+strlen(buffer), n->methodname);
333 strcpy (buffer+strlen(buffer), ": ");
334 utf_sprint(buffer+strlen(buffer), n->descriptor);
335 strcpy(buffer+strlen(buffer), " for class ");
336 utf_sprint(buffer+strlen(buffer), n->classname);
340 MFREE(buffer, char, buffer_len);
347 /* no function was found, display warning */
350 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
352 buffer = MNEW(char, buffer_len);
354 strcpy(buffer, "warning: native function ");
355 utf_sprint(buffer + strlen(buffer), mname);
356 strcpy(buffer + strlen(buffer), ": ");
357 utf_sprint(buffer + strlen(buffer), desc);
358 strcpy(buffer + strlen(buffer), " not found in class ");
359 utf_sprint(buffer + strlen(buffer), cname);
363 MFREE(buffer, char, buffer_len);
367 /* keep compiler happy */
372 /********************** function: javastring_new *******************************
374 creates a new object of type java/lang/String with the text of
375 the specified utf8-string
377 return: pointer to the string or NULL if memory is exhausted.
379 *******************************************************************************/
381 java_lang_String *javastring_new(utf *u)
383 char *utf_ptr = u->text; /* current utf character in utf string */
384 int utflength = utf_strlen(u); /* length of utf-string if uncompressed */
385 java_lang_String *s; /* result-string */
389 s = (java_lang_String *) builtin_new(class_java_lang_String);
390 a = builtin_newarray_char(utflength);
392 /* javastring or character-array could not be created */
396 /* decompress utf-string */
397 for (i = 0; i < utflength; i++)
398 a->data[i] = utf_nextu2(&utf_ptr);
400 /* set fields of the javastring-object */
403 s->count = utflength;
409 /********************** function: javastring_new_char **************************
411 creates a new java/lang/String object which contains the convertet
412 C-string passed via text.
414 return: the object pointer or NULL if memory is exhausted.
416 *******************************************************************************/
418 java_lang_String *javastring_new_char(char *text)
421 s4 len = strlen(text); /* length of the string */
422 java_lang_String *s; /* result-string */
425 s = (java_lang_String *) builtin_new(class_java_lang_String);
426 a = builtin_newarray_char(len);
428 /* javastring or character-array could not be created */
433 for (i = 0; i < len; i++)
434 a->data[i] = text[i];
436 /* set fields of the javastring-object */
445 /************************* function javastring_tochar **************************
447 converts a Java string into a C string.
449 return: pointer to C string
451 Caution: every call of this function overwrites the previous string !!!
453 *******************************************************************************/
455 static char stringbuffer[MAXSTRINGSIZE];
457 char *javastring_tochar(java_objectheader *so)
459 java_lang_String *s = (java_lang_String *) so;
471 if (s->count > MAXSTRINGSIZE)
474 for (i = 0; i < s->count; i++)
475 stringbuffer[i] = a->data[s->offset + i];
477 stringbuffer[i] = '\0';
483 /****************** function class_findfield_approx ****************************
485 searches in 'classinfo'-structure for a field with the
488 *******************************************************************************/
490 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
494 for (i = 0; i < c->fieldscount; i++) {
495 /* compare field names */
496 if ((c->fields[i].name == name))
497 return &(c->fields[i]);
500 /* field was not found, raise exception */
501 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
507 s4 class_findfield_index_approx(classinfo *c, utf *name)
511 for (i = 0; i < c->fieldscount; i++) {
512 /* compare field names */
513 if ((c->fields[i].name == name))
517 /* field was not found, raise exception */
518 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
524 /********************** function: native_new_and_init *************************
526 Creates a new object on the heap and calls the initializer.
527 Returns the object pointer or NULL if memory is exhausted.
529 *******************************************************************************/
531 java_objectheader *native_new_and_init(classinfo *c)
534 java_objectheader *o;
537 return *exceptionptr;
539 o = builtin_new(c); /* create object */
544 /* find initializer */
546 m = class_findmethod(c,
547 utf_new_char("<init>"),
548 utf_new_char("()V"));
550 if (!m) { /* initializer not found */
552 char logtext[MAXLOGTEXT];
553 sprintf(logtext, "Warning: class has no instance-initializer: ");
554 utf_sprint_classname(logtext + strlen(logtext), c->name);
560 /* call initializer */
562 asm_calljavafunction(m, o, NULL, NULL, NULL);
568 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
571 java_objectheader *o;
574 return *exceptionptr;
576 o = builtin_new(c); /* create object */
581 /* find initializer */
583 m = class_findmethod(c,
584 utf_new_char("<init>"),
585 utf_new_char("(Ljava/lang/String;)V"));
587 if (!m) { /* initializer not found */
589 char logtext[MAXLOGTEXT];
590 sprintf(logtext, "Warning: class has no instance-initializer: ");
591 utf_sprint_classname(logtext + strlen(logtext), c->name);
597 /* call initializer */
599 asm_calljavafunction(m, o, s, NULL, NULL);
605 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
608 java_objectheader *o;
611 return *exceptionptr;
613 o = builtin_new(c); /* create object */
617 /* find initializer */
619 m = class_findmethod(c,
620 utf_new_char("<init>"),
621 utf_new_char("(I)V"));
623 if (!m) { /* initializer not found */
625 char logtext[MAXLOGTEXT];
626 sprintf(logtext, "Warning: class has no instance-initializer: ");
627 utf_sprint_classname(logtext + strlen(logtext), c->name);
633 /* call initializer */
635 #if defined(__I386__) || defined(__POWERPC__)
636 asm_calljavafunction(m, o, (void *) i, NULL, NULL);
638 asm_calljavafunction(m, o, (void *) (s8) i, NULL, NULL);
645 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
648 java_objectheader *o;
651 return *exceptionptr;
653 o = builtin_new(c); /* create object */
657 /* find initializer */
659 m = class_findmethod(c,
660 utf_new_char("<init>"),
661 utf_new_char("(Ljava/lang/Throwable;)V"));
663 if (!m) { /* initializer not found */
665 char logtext[MAXLOGTEXT];
666 sprintf(logtext, "Warning: class has no instance-initializer: ");
667 utf_sprint_classname(logtext + strlen(logtext), c->name);
673 /* call initializer */
675 asm_calljavafunction(m, o, t, NULL, NULL);
681 /******************** function: stringtable_update ****************************
683 traverses the javastring hashtable and sets the vftbl-entries of
684 javastrings which were temporarily set to NULL, because
685 java.lang.Object was not yet loaded
687 *******************************************************************************/
689 void stringtable_update ()
691 java_lang_String *js;
693 literalstring *s; /* hashtable entry */
696 for (i = 0; i < string_hash.size; i++) {
697 s = string_hash.ptr[i];
701 js = (java_lang_String *) s->string;
703 if (!js || !js->value)
704 /* error in hashtable found */
705 panic("invalid literalstring in hashtable");
709 if (!js->header.vftbl)
710 /* vftbl of javastring is NULL */
711 js->header.vftbl = class_java_lang_String->vftbl;
713 if (!a->header.objheader.vftbl)
714 /* vftbl of character-array is NULL */
715 a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
717 /* follow link in external hash chain */
725 /************************* function: u2_utflength ***************************
727 returns the utf length in bytes of a u2 array
729 *****************************************************************************/
731 u4 u2_utflength(u2 *text, u4 u2_length)
733 u4 result_len = 0; /* utf length in bytes */
734 u2 ch; /* current unicode character */
737 for (len = 0; len < u2_length; len++) {
738 /* next unicode character */
741 /* determine bytes required to store unicode character as utf */
742 if (ch && (ch < 0x80))
754 /********************* function: utf_new_u2 ***********************************
756 make utf symbol from u2 array,
757 if isclassname is true '.' is replaced by '/'
759 *******************************************************************************/
761 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
763 char *buffer; /* memory buffer for unicode characters */
764 char *pos; /* pointer to current position in buffer */
765 u4 left; /* unicode characters left */
766 u4 buflength; /* utf length in bytes of the u2 array */
767 utf *result; /* resulting utf-string */
770 /* determine utf length in bytes and allocate memory */
771 /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */
772 buflength = u2_utflength(unicode_pos, unicode_length);
773 buffer = MNEW(char, buflength);
778 for (i = 0; i++ < unicode_length; unicode_pos++) {
779 /* next unicode character */
782 if ((c != 0) && (c < 0x80)) {
785 if ((int) left < 0) break;
786 /* convert classname */
787 if (isclassname && c == '.')
792 } else if (c < 0x800) {
794 unsigned char high = c >> 6;
795 unsigned char low = c & 0x3F;
797 if ((int) left < 0) break;
798 *pos++ = high | 0xC0;
804 char mid = (c >> 6) & 0x3F;
807 if ((int) left < 0) break;
808 *pos++ = high | 0xE0;
814 /* insert utf-string into symbol-table */
815 result = utf_new(buffer,buflength);
817 MFREE(buffer, char, buflength);
823 /********************* function: javastring_toutf *****************************
825 make utf symbol from javastring
827 *******************************************************************************/
829 utf *javastring_toutf(java_lang_String *string, bool isclassname)
831 java_lang_String *str = (java_lang_String *) string;
833 /* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
834 /* fflush(stdout); */
836 return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
840 /********************* function: literalstring_u2 *****************************
842 searches for the javastring with the specified u2-array in
843 the string hashtable, if there is no such string a new one is
846 if copymode is true a copy of the u2-array is made
848 *******************************************************************************/
850 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
853 literalstring *s; /* hashtable element */
854 java_lang_String *js; /* u2-array wrapped in javastring */
855 java_chararray *stringdata; /* copy of u2-array */
861 //#define DEBUG_LITERALSTRING_U2
862 #ifdef DEBUG_LITERALSTRING_U2
863 printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
867 /* find location in hashtable */
868 key = unicode_hashkey(a->data + offset, length);
869 slot = key & (string_hash.size - 1);
870 s = string_hash.ptr[slot];
873 js = (java_lang_String *) s->string;
875 if (length == js->count) {
877 for (i = 0; i < length; i++) {
878 if (a->data[offset + i] != js->value->data[i])
882 /* string already in hashtable, free memory */
884 lit_mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
886 #ifdef DEBUG_LITERALSTRING_U2
887 printf("literalstring_u2: foundentry at %p\n", js);
888 utf_display(javastring_toutf(js, 0));
892 return (java_objectheader *) js;
896 /* follow link in external hash chain */
901 /* create copy of u2-array for new javastring */
902 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
903 stringdata = lit_mem_alloc(arraysize);
904 /* memcpy(stringdata, a, arraysize); */
905 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
906 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
912 /* location in hashtable found, complete arrayheader */
913 stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
914 stringdata->header.size = length;
916 /* if we use eager loading, we have to check loaded String class */
918 class_java_lang_String =
919 class_new_intern(utf_new_char("java/lang/String"));
921 if (!class_load(class_java_lang_String))
924 list_addfirst(&unlinkedclasses, class_java_lang_String);
927 /* create new javastring */
928 js = LNEW(java_lang_String);
929 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
930 initObjectLock(&js->header);
932 js->header.vftbl = class_java_lang_String->vftbl;
933 js->value = stringdata;
937 #ifdef DEBUG_LITERALSTRING_U2
938 printf("literalstring_u2: newly created at %p\n", js);
939 utf_display(javastring_toutf(js, 0));
944 /* create new literalstring */
945 s = NEW(literalstring);
946 s->hashlink = string_hash.ptr[slot];
947 s->string = (java_objectheader *) js;
948 string_hash.ptr[slot] = s;
950 /* update number of hashtable entries */
951 string_hash.entries++;
953 /* reorganization of hashtable */
954 if (string_hash.entries > (string_hash.size * 2)) {
955 /* reorganization of hashtable, average length of
956 the external chains is approx. 2 */
960 hashtable newhash; /* the new hashtable */
962 /* create new hashtable, double the size */
963 init_hashtable(&newhash, string_hash.size * 2);
964 newhash.entries = string_hash.entries;
966 /* transfer elements to new hashtable */
967 for (i = 0; i < string_hash.size; i++) {
968 s = string_hash.ptr[i];
970 literalstring *nexts = s->hashlink;
971 js = (java_lang_String *) s->string;
972 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
974 s->hashlink = newhash.ptr[slot];
975 newhash.ptr[slot] = s;
977 /* follow link in external hash chain */
982 /* dispose old table */
983 MFREE(string_hash.ptr, void*, string_hash.size);
984 string_hash = newhash;
987 return (java_objectheader *) js;
991 /******************** Function: literalstring_new *****************************
993 creates a new javastring with the text of the utf-symbol
994 and inserts it into the string hashtable
996 *******************************************************************************/
998 java_objectheader *literalstring_new(utf *u)
1000 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
1001 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
1002 java_chararray *a; /* u2-array constructed from utf string */
1005 /* allocate memory */
1006 a = lit_mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1008 /* convert utf-string to u2-array */
1009 for (i = 0; i < utflength; i++)
1010 a->data[i] = utf_nextu2(&utf_ptr);
1012 return literalstring_u2(a, utflength, 0, false);
1016 /********************** function: literalstring_free **************************
1018 removes a javastring from memory
1020 ******************************************************************************/
1022 void literalstring_free(java_objectheader* sobj)
1024 java_lang_String *s = (java_lang_String *) sobj;
1025 java_chararray *a = s->value;
1027 /* dispose memory of java.lang.String object */
1028 LFREE(s, java_lang_String);
1030 /* dispose memory of java-characterarray */
1031 LFREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1035 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1039 /* XXX this kind of copying does not work (in the general
1040 * case). The interface tables would have to be copied, too. I
1041 * don't see why we should make a copy anyway. -Edwin
1043 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1044 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1045 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1050 /******************************************************************************************
1052 creates method signature (excluding return type) from array of
1053 class-objects representing the parameters of the method
1055 *******************************************************************************************/
1058 utf *create_methodsig(java_objectarray* types, char *retType)
1060 char *buffer; /* buffer for building the desciptor */
1061 char *pos; /* current position in buffer */
1062 utf *result; /* the method signature */
1063 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1066 if (!types) return NULL;
1068 /* determine required buffer-size */
1069 for (i = 0; i < types->header.size; i++) {
1070 classinfo *c = (classinfo *) types->data[i];
1071 buffer_size = buffer_size + c->name->blength + 2;
1074 if (retType) buffer_size += strlen(retType);
1076 /* allocate buffer */
1077 buffer = MNEW(u1, buffer_size);
1080 /* method-desciptor starts with parenthesis */
1083 for (i = 0; i < types->header.size; i++) {
1086 /* current argument */
1087 classinfo *c = (classinfo *) types->data[i];
1089 /* current position in utf-text */
1090 char *utf_ptr = c->name->text;
1092 /* determine type of argument */
1093 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1095 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1096 *pos++ = *utf_ptr; /* copy text */
1100 /* check for primitive types */
1101 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1102 char *utf_pos = utf_ptr - 1;
1103 char *primitive = primitivetype_table[j].wrapname;
1106 while (utf_pos < utf_end(c->name)) {
1107 if (*utf_pos++ != *primitive++) goto nomatch;
1110 /* primitive type found */
1111 *pos++ = primitivetype_table[j].typesig;
1118 /* no primitive type and no arrayclass, so must be object */
1122 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1136 for (i = 0; i < strlen(retType); i++) {
1137 *pos++ = retType[i];
1141 /* create utf-string */
1142 result = utf_new(buffer, (pos - buffer));
1143 MFREE(buffer, u1, buffer_size);
1149 /******************************************************************************************
1151 retrieve the next argument or returntype from a descriptor
1152 and return the corresponding class
1154 *******************************************************************************************/
1156 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1158 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1159 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1162 panic("illegal descriptor");
1164 if (skip) return NULL;
1166 use_class_as_object(c);
1171 /* get_parametertypes **********************************************************
1173 use the descriptor of a method to generate a java/lang/Class array
1174 which contains the classes of the parametertypes of the method
1176 *******************************************************************************/
1178 java_objectarray* get_parametertypes(methodinfo *m)
1180 utf *descr = m->descriptor; /* method-descriptor */
1181 char *utf_ptr = descr->text; /* current position in utf-text */
1182 char *desc_end = utf_end(descr); /* points behind utf string */
1183 java_objectarray* result;
1184 int parametercount = 0;
1188 utf_nextu2(&utf_ptr);
1190 /* determine number of parameters */
1191 while (*utf_ptr != ')') {
1192 get_type(&utf_ptr, desc_end, true);
1196 /* create class-array */
1197 result = builtin_anewarray(parametercount, class_java_lang_Class);
1199 utf_ptr = descr->text;
1200 utf_nextu2(&utf_ptr);
1202 /* get returntype classes */
1203 for (i = 0; i < parametercount; i++)
1205 (java_objectheader *) get_type(&utf_ptr, desc_end, false);
1211 /* get_exceptiontypes **********************************************************
1213 get the exceptions which can be thrown by a method
1215 *******************************************************************************/
1217 java_objectarray* get_exceptiontypes(methodinfo *m) {
1218 u2 exccount=m->thrownexceptionscount;
1220 java_objectarray *result;
1221 /* create class-array */
1222 result = builtin_anewarray(exccount, class_java_lang_Class);
1223 for (i=0;i<exccount;i++) {
1224 java_objectheader *oh=(java_objectheader*)(m->thrownexceptions[i]);
1225 use_class_as_object(oh);
1235 /******************************************************************************************
1237 get the returntype class of a method
1239 *******************************************************************************************/
1241 classinfo *get_returntype(methodinfo *m)
1243 char *utf_ptr; /* current position in utf-text */
1244 char *desc_end; /* points behind utf string */
1245 utf *desc = m->descriptor; /* method-descriptor */
1247 utf_ptr = desc->text;
1248 desc_end = utf_end(desc);
1250 /* ignore parametertypes */
1251 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1254 return get_type(&utf_ptr,desc_end, false);
1258 /*****************************************************************************/
1259 /*****************************************************************************/
1262 /*--------------------------------------------------------*/
1263 void printNativeCall(nativeCall nc) {
1266 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1267 for (i=0; i<nc.methCnt; i++) {
1268 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1270 for (j=0; j<nc.callCnt[i]; j++) {
1271 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1272 nc.methods[i].methodCalls[j].classname,
1273 nc.methods[i].methodCalls[j].methodname,
1274 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1277 printf("-+++++--------------------\n");fflush(stdout);
1280 /*--------------------------------------------------------*/
1281 void printCompNativeCall(nativeCompCall nc) {
1283 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1284 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1285 utf_display(nc.classname); fflush(stdout);
1287 for (i=0; i<nc.methCnt; i++) {
1288 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1289 utf_display(nc.methods[i].methodname); fflush(stdout);
1290 utf_display(nc.methods[i].descriptor);fflush(stdout);
1291 printf("\n");fflush(stdout);
1293 for (j=0; j<nc.callCnt[i]; j++) {
1294 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1295 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1296 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1297 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1298 printf("\n");fflush(stdout);
1301 printf("---------------------\n");fflush(stdout);
1305 /*--------------------------------------------------------*/
1306 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1319 /*--------------------------------------------------------*/
1320 nativeCall* findNativeClassCalls(char *aclassname ) {
1323 for (i=0;i<NATIVECALLSSIZE; i++) {
1324 /* convert table to utf later to speed up search */
1325 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1326 return &nativeCalls[i];
1331 /*--------------------------------------------------------*/
1332 /*--------------------------------------------------------*/
1333 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1337 ncc->classname = utf_new_char(nc.classname);
1338 ncc->methCnt = nc.methCnt;
1340 for (i=0; i<nc.methCnt; i++) {
1341 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1342 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1343 ncc->callCnt[i] = nc.callCnt[i];
1345 for (j=0; j<nc.callCnt[i]; j++) {
1347 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1349 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1350 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1351 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1354 ncc->methods[i].methodCalls[j].methodname = NULL;
1355 ncc->methods[i].methodCalls[j].descriptor = NULL;
1363 /*--------------------------------------------------------*/
1365 bool natcall2utf(bool natcallcompdone) {
1368 if (natcallcompdone)
1371 for (i=0;i<NATIVECALLSSIZE; i++) {
1372 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1378 /*--------------------------------------------------------*/
1381 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end,classinfo **start)
1383 #if defined(__GNUC__)
1384 #warning platform dependend
1386 java_objectarray *tmpArray;
1388 classinfo **current;
1390 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1391 /*printf("end %p, start %p, size %ld\n",end,start,size);*/
1392 if (!class_java_lang_Class)
1393 class_java_lang_Class = class_new(utf_new_char ("java/lang/Class"));
1394 if (!class_java_lang_SecurityManager)
1395 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1397 if (start==class_java_lang_SecurityManager) {
1402 tmpArray=builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1404 for(i=0,current=start;i<size;i++,current--) {
1406 /* printf("%d\n",i);
1407 utf_display(c->name);*/
1408 use_class_as_object(c);
1409 tmpArray->data[i]=c;
1415 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end,classinfo **start)
1417 #if defined(__GNUC__)
1418 #warning platform dependend
1421 classinfo **current;
1423 classinfo *privilegedAction;
1424 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1425 /* log_text("builtin_asm_getclassloader");
1426 printf("end %p, start %p, size %ld\n",end,start,size);*/
1428 if (!class_java_lang_SecurityManager)
1429 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1431 if (start==class_java_lang_SecurityManager) {
1437 privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1439 for(i=0,current=start;i<size;i++,current--) {
1441 if (c==privilegedAction) return NULL;
1442 if (c->classloader) return c->classloader;
1450 log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1451 init_systemclassloader();
1453 return SystemClassLoader;*/
1457 * These are local overrides for various environment variables in Emacs.
1458 * Please do not remove this and leave it at the end of the file, where
1459 * Emacs will automagically detect them.
1460 * ---------------------------------------------------------------------
1463 * indent-tabs-mode: t