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 1361 2004-07-28 10:51:14Z 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 #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 js->header.vftbl = class_java_lang_String->vftbl;
930 js->value = stringdata;
934 #ifdef DEBUG_LITERALSTRING_U2
935 printf("literalstring_u2: newly created at %p\n", js);
936 utf_display(javastring_toutf(js, 0));
941 /* create new literalstring */
942 s = NEW(literalstring);
943 s->hashlink = string_hash.ptr[slot];
944 s->string = (java_objectheader *) js;
945 string_hash.ptr[slot] = s;
947 /* update number of hashtable entries */
948 string_hash.entries++;
950 /* reorganization of hashtable */
951 if (string_hash.entries > (string_hash.size * 2)) {
952 /* reorganization of hashtable, average length of
953 the external chains is approx. 2 */
957 hashtable newhash; /* the new hashtable */
959 /* create new hashtable, double the size */
960 init_hashtable(&newhash, string_hash.size * 2);
961 newhash.entries = string_hash.entries;
963 /* transfer elements to new hashtable */
964 for (i = 0; i < string_hash.size; i++) {
965 s = string_hash.ptr[i];
967 literalstring *nexts = s->hashlink;
968 js = (java_lang_String *) s->string;
969 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
971 s->hashlink = newhash.ptr[slot];
972 newhash.ptr[slot] = s;
974 /* follow link in external hash chain */
979 /* dispose old table */
980 MFREE(string_hash.ptr, void*, string_hash.size);
981 string_hash = newhash;
984 return (java_objectheader *) js;
988 /******************** Function: literalstring_new *****************************
990 creates a new javastring with the text of the utf-symbol
991 and inserts it into the string hashtable
993 *******************************************************************************/
995 java_objectheader *literalstring_new(utf *u)
997 char *utf_ptr = u->text; /* pointer to current unicode character in utf string */
998 u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */
999 java_chararray *a; /* u2-array constructed from utf string */
1002 /* allocate memory */
1003 a = lit_mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1005 /* convert utf-string to u2-array */
1006 for (i = 0; i < utflength; i++)
1007 a->data[i] = utf_nextu2(&utf_ptr);
1009 return literalstring_u2(a, utflength, 0, false);
1013 /********************** function: literalstring_free **************************
1015 removes a javastring from memory
1017 ******************************************************************************/
1019 void literalstring_free(java_objectheader* sobj)
1021 java_lang_String *s = (java_lang_String *) sobj;
1022 java_chararray *a = s->value;
1024 /* dispose memory of java.lang.String object */
1025 LFREE(s, java_lang_String);
1027 /* dispose memory of java-characterarray */
1028 LFREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1032 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1036 /* XXX this kind of copying does not work (in the general
1037 * case). The interface tables would have to be copied, too. I
1038 * don't see why we should make a copy anyway. -Edwin
1040 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1041 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1042 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1047 /******************************************************************************************
1049 creates method signature (excluding return type) from array of
1050 class-objects representing the parameters of the method
1052 *******************************************************************************************/
1055 utf *create_methodsig(java_objectarray* types, char *retType)
1057 char *buffer; /* buffer for building the desciptor */
1058 char *pos; /* current position in buffer */
1059 utf *result; /* the method signature */
1060 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1063 if (!types) return NULL;
1065 /* determine required buffer-size */
1066 for (i = 0; i < types->header.size; i++) {
1067 classinfo *c = (classinfo *) types->data[i];
1068 buffer_size = buffer_size + c->name->blength + 2;
1071 if (retType) buffer_size += strlen(retType);
1073 /* allocate buffer */
1074 buffer = MNEW(u1, buffer_size);
1077 /* method-desciptor starts with parenthesis */
1080 for (i = 0; i < types->header.size; i++) {
1083 /* current argument */
1084 classinfo *c = (classinfo *) types->data[i];
1086 /* current position in utf-text */
1087 char *utf_ptr = c->name->text;
1089 /* determine type of argument */
1090 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1092 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1093 *pos++ = *utf_ptr; /* copy text */
1097 /* check for primitive types */
1098 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1099 char *utf_pos = utf_ptr - 1;
1100 char *primitive = primitivetype_table[j].wrapname;
1103 while (utf_pos < utf_end(c->name)) {
1104 if (*utf_pos++ != *primitive++) goto nomatch;
1107 /* primitive type found */
1108 *pos++ = primitivetype_table[j].typesig;
1115 /* no primitive type and no arrayclass, so must be object */
1119 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1133 for (i = 0; i < strlen(retType); i++) {
1134 *pos++ = retType[i];
1138 /* create utf-string */
1139 result = utf_new(buffer, (pos - buffer));
1140 MFREE(buffer, u1, buffer_size);
1146 /******************************************************************************************
1148 retrieve the next argument or returntype from a descriptor
1149 and return the corresponding class
1151 *******************************************************************************************/
1153 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1155 classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1156 (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1159 panic("illegal descriptor");
1161 if (skip) return NULL;
1163 use_class_as_object(c);
1168 /* get_parametertypes **********************************************************
1170 use the descriptor of a method to generate a java/lang/Class array
1171 which contains the classes of the parametertypes of the method
1173 *******************************************************************************/
1175 java_objectarray* get_parametertypes(methodinfo *m)
1177 utf *descr = m->descriptor; /* method-descriptor */
1178 char *utf_ptr = descr->text; /* current position in utf-text */
1179 char *desc_end = utf_end(descr); /* points behind utf string */
1180 java_objectarray* result;
1181 int parametercount = 0;
1185 utf_nextu2(&utf_ptr);
1187 /* determine number of parameters */
1188 while (*utf_ptr != ')') {
1189 get_type(&utf_ptr, desc_end, true);
1193 /* create class-array */
1194 result = builtin_anewarray(parametercount, class_java_lang_Class);
1196 utf_ptr = descr->text;
1197 utf_nextu2(&utf_ptr);
1199 /* get returntype classes */
1200 for (i = 0; i < parametercount; i++)
1202 (java_objectheader *) get_type(&utf_ptr, desc_end, false);
1208 /* get_exceptiontypes **********************************************************
1210 get the exceptions which can be thrown by a method
1212 *******************************************************************************/
1214 java_objectarray* get_exceptiontypes(methodinfo *m) {
1215 u2 exccount=m->thrownexceptionscount;
1217 java_objectarray *result;
1218 /* create class-array */
1219 result = builtin_anewarray(exccount, class_java_lang_Class);
1220 for (i=0;i<exccount;i++) {
1221 java_objectheader *oh=(java_objectheader*)(m->thrownexceptions[i]);
1222 use_class_as_object(oh);
1232 /******************************************************************************************
1234 get the returntype class of a method
1236 *******************************************************************************************/
1238 classinfo *get_returntype(methodinfo *m)
1240 char *utf_ptr; /* current position in utf-text */
1241 char *desc_end; /* points behind utf string */
1242 utf *desc = m->descriptor; /* method-descriptor */
1244 utf_ptr = desc->text;
1245 desc_end = utf_end(desc);
1247 /* ignore parametertypes */
1248 while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1251 return get_type(&utf_ptr,desc_end, false);
1255 /*****************************************************************************/
1256 /*****************************************************************************/
1259 /*--------------------------------------------------------*/
1260 void printNativeCall(nativeCall nc) {
1263 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1264 for (i=0; i<nc.methCnt; i++) {
1265 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1267 for (j=0; j<nc.callCnt[i]; j++) {
1268 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1269 nc.methods[i].methodCalls[j].classname,
1270 nc.methods[i].methodCalls[j].methodname,
1271 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1274 printf("-+++++--------------------\n");fflush(stdout);
1277 /*--------------------------------------------------------*/
1278 void printCompNativeCall(nativeCompCall nc) {
1280 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1281 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1282 utf_display(nc.classname); fflush(stdout);
1284 for (i=0; i<nc.methCnt; i++) {
1285 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1286 utf_display(nc.methods[i].methodname); fflush(stdout);
1287 utf_display(nc.methods[i].descriptor);fflush(stdout);
1288 printf("\n");fflush(stdout);
1290 for (j=0; j<nc.callCnt[i]; j++) {
1291 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1292 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1293 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1294 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1295 printf("\n");fflush(stdout);
1298 printf("---------------------\n");fflush(stdout);
1302 /*--------------------------------------------------------*/
1303 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1316 /*--------------------------------------------------------*/
1317 nativeCall* findNativeClassCalls(char *aclassname ) {
1320 for (i=0;i<NATIVECALLSSIZE; i++) {
1321 /* convert table to utf later to speed up search */
1322 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1323 return &nativeCalls[i];
1328 /*--------------------------------------------------------*/
1329 /*--------------------------------------------------------*/
1330 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1334 ncc->classname = utf_new_char(nc.classname);
1335 ncc->methCnt = nc.methCnt;
1337 for (i=0; i<nc.methCnt; i++) {
1338 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1339 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1340 ncc->callCnt[i] = nc.callCnt[i];
1342 for (j=0; j<nc.callCnt[i]; j++) {
1344 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1346 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1347 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1348 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1351 ncc->methods[i].methodCalls[j].methodname = NULL;
1352 ncc->methods[i].methodCalls[j].descriptor = NULL;
1360 /*--------------------------------------------------------*/
1362 bool natcall2utf(bool natcallcompdone) {
1365 if (natcallcompdone)
1368 for (i=0;i<NATIVECALLSSIZE; i++) {
1369 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1375 /*--------------------------------------------------------*/
1378 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end,classinfo **start)
1380 #if defined(__GNUC__)
1381 #warning platform dependend
1383 java_objectarray *tmpArray;
1385 classinfo **current;
1387 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1388 /*printf("end %p, start %p, size %ld\n",end,start,size);*/
1389 if (!class_java_lang_Class)
1390 class_java_lang_Class = class_new(utf_new_char ("java/lang/Class"));
1391 if (!class_java_lang_SecurityManager)
1392 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1394 if (start==class_java_lang_SecurityManager) {
1399 tmpArray=builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1401 for(i=0,current=start;i<size;i++,current--) {
1403 /* printf("%d\n",i);
1404 utf_display(c->name);*/
1405 use_class_as_object(c);
1406 tmpArray->data[i]=c;
1412 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end,classinfo **start)
1414 #if defined(__GNUC__)
1415 #warning platform dependend
1418 classinfo **current;
1420 classinfo *privilegedAction;
1421 size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1422 /* log_text("builtin_asm_getclassloader");
1423 printf("end %p, start %p, size %ld\n",end,start,size);*/
1425 if (!class_java_lang_SecurityManager)
1426 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1428 if (start==class_java_lang_SecurityManager) {
1434 privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1436 for(i=0,current=start;i<size;i++,current--) {
1438 if (c==privilegedAction) return NULL;
1439 if (c->classloader) return c->classloader;
1447 log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1448 init_systemclassloader();
1450 return SystemClassLoader;*/
1454 * These are local overrides for various environment variables in Emacs.
1455 * Please do not remove this and leave it at the end of the file, where
1456 * Emacs will automagically detect them.
1457 * ---------------------------------------------------------------------
1460 * indent-tabs-mode: t