1 /* src/native/native.c - table of native functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
31 Changes: Christian Thalinger
33 $Id: native.c 2696 2005-06-14 22:31:37Z twisti $
40 #if !defined(STATIC_CLASSPATH)
41 # include "src/libltdl/ltdl.h"
46 #include "cacao/cacao.h"
47 #include "mm/memory.h"
48 #include "native/jni.h"
49 #include "native/native.h"
50 #include "native/include/java_lang_Throwable.h"
51 #include "toolbox/logging.h"
52 #include "vm/builtin.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
55 #include "vm/loader.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/stringlocal.h"
59 #include "vm/tables.h"
60 #include "vm/jit/asmpart.h"
61 #include "vm/jit/jit.h"
64 /* include table of native functions ******************************************/
66 #include "native/include/java_lang_Cloneable.h"
67 #include "native/include/java_util_Properties.h"
68 #include "native/include/java_io_InputStream.h"
69 #include "native/include/java_io_PrintStream.h"
71 #include "native/include/gnu_classpath_VMStackWalker.h"
72 #include "native/include/gnu_classpath_VMSystemProperties.h"
73 #include "native/include/java_lang_Class.h"
74 #include "native/include/java_lang_Object.h"
75 #include "native/include/java_lang_VMClass.h"
76 #include "native/include/java_lang_VMClassLoader.h"
77 #include "native/include/java_lang_VMObject.h"
78 #include "native/include/java_lang_VMRuntime.h"
79 #include "native/include/java_lang_VMString.h"
80 #include "native/include/java_lang_VMSystem.h"
81 #include "native/include/java_lang_VMThread.h"
82 #include "native/include/java_lang_VMThrowable.h"
83 #include "native/include/java_lang_reflect_Constructor.h"
84 #include "native/include/java_lang_reflect_Field.h"
85 #include "native/include/java_lang_reflect_Proxy.h"
86 #include "native/include/java_lang_reflect_Method.h"
87 #include "native/include/java_security_VMAccessController.h"
89 #if defined(STATIC_CLASSPATH)
91 /* these are required to prevent compiler warnings */
93 #include "native/include/java_net_DatagramPacket.h"
94 #include "native/include/java_net_InetAddress.h"
95 #include "native/include/java_net_SocketImpl.h"
97 #include "native/include/gnu_java_net_PlainDatagramSocketImpl.h"
98 #include "native/include/gnu_java_net_PlainSocketImpl.h"
99 #include "native/include/gnu_java_nio_PipeImpl.h"
100 #include "native/include/gnu_java_nio_channels_FileChannelImpl.h"
101 #include "native/include/gnu_java_nio_charset_iconv_IconvEncoder.h"
102 #include "native/include/gnu_java_nio_charset_iconv_IconvDecoder.h"
103 #include "native/include/java_lang_VMProcess.h"
104 #include "native/include/java_nio_MappedByteBufferImpl.h"
105 #include "native/include/java_nio_channels_spi_SelectorProvider.h"
107 /* now include the native table */
109 #include "native/nativetable.inc"
111 #else /* defined(STATIC_CLASSPATH) */
113 /* Ensure that symbols for functions implemented within CACAO are used and */
114 /* exported to dlopen. */
116 static functionptr dummynativetable[] = {
117 (functionptr) Java_gnu_classpath_VMStackWalker_getClassContext,
119 (functionptr) Java_gnu_classpath_VMSystemProperties_preInit,
121 (functionptr) Java_java_lang_VMClass_isInstance,
122 (functionptr) Java_java_lang_VMClass_isAssignableFrom,
123 (functionptr) Java_java_lang_VMClass_isInterface,
124 (functionptr) Java_java_lang_VMClass_isPrimitive,
125 (functionptr) Java_java_lang_VMClass_getName,
126 (functionptr) Java_java_lang_VMClass_getSuperclass,
127 (functionptr) Java_java_lang_VMClass_getInterfaces,
128 (functionptr) Java_java_lang_VMClass_getComponentType,
129 (functionptr) Java_java_lang_VMClass_getModifiers,
130 (functionptr) Java_java_lang_VMClass_getDeclaringClass,
131 (functionptr) Java_java_lang_VMClass_getDeclaredClasses,
132 (functionptr) Java_java_lang_VMClass_getDeclaredFields,
133 (functionptr) Java_java_lang_VMClass_getDeclaredMethods,
134 (functionptr) Java_java_lang_VMClass_getDeclaredConstructors,
135 (functionptr) Java_java_lang_VMClass_getClassLoader,
136 (functionptr) Java_java_lang_VMClass_forName,
137 (functionptr) Java_java_lang_VMClass_isArray,
138 (functionptr) Java_java_lang_VMClass_initialize,
139 (functionptr) Java_java_lang_VMClass_loadArrayClass,
140 (functionptr) Java_java_lang_VMClass_throwException,
142 (functionptr) Java_java_lang_VMClassLoader_defineClass,
143 (functionptr) Java_java_lang_VMClassLoader_resolveClass,
144 (functionptr) Java_java_lang_VMClassLoader_loadClass,
145 (functionptr) Java_java_lang_VMClassLoader_getPrimitiveClass,
146 (functionptr) Java_java_lang_VMClassLoader_nativeGetResources,
148 (functionptr) Java_java_lang_VMObject_getClass,
149 (functionptr) Java_java_lang_VMObject_clone,
150 (functionptr) Java_java_lang_VMObject_notify,
151 (functionptr) Java_java_lang_VMObject_notifyAll,
152 (functionptr) Java_java_lang_VMObject_wait,
154 (functionptr) Java_java_lang_VMRuntime_availableProcessors,
155 (functionptr) Java_java_lang_VMRuntime_freeMemory,
156 (functionptr) Java_java_lang_VMRuntime_totalMemory,
157 (functionptr) Java_java_lang_VMRuntime_maxMemory,
158 (functionptr) Java_java_lang_VMRuntime_gc,
159 (functionptr) Java_java_lang_VMRuntime_runFinalization,
160 (functionptr) Java_java_lang_VMRuntime_runFinalizationForExit,
161 (functionptr) Java_java_lang_VMRuntime_traceInstructions,
162 (functionptr) Java_java_lang_VMRuntime_traceMethodCalls,
163 (functionptr) Java_java_lang_VMRuntime_runFinalizersOnExit,
164 (functionptr) Java_java_lang_VMRuntime_exit,
165 (functionptr) Java_java_lang_VMRuntime_nativeLoad,
166 (functionptr) Java_java_lang_VMRuntime_mapLibraryName,
168 (functionptr) Java_java_lang_VMString_intern,
170 (functionptr) Java_java_lang_VMSystem_arraycopy,
171 (functionptr) Java_java_lang_VMSystem_identityHashCode,
173 (functionptr) Java_java_lang_VMThread_start,
174 (functionptr) Java_java_lang_VMThread_interrupt,
175 (functionptr) Java_java_lang_VMThread_isInterrupted,
176 (functionptr) Java_java_lang_VMThread_suspend,
177 (functionptr) Java_java_lang_VMThread_resume,
178 (functionptr) Java_java_lang_VMThread_nativeSetPriority,
179 (functionptr) Java_java_lang_VMThread_nativeStop,
180 (functionptr) Java_java_lang_VMThread_currentThread,
181 (functionptr) Java_java_lang_VMThread_yield,
182 (functionptr) Java_java_lang_VMThread_interrupted,
183 (functionptr) Java_java_lang_VMThread_holdsLock,
185 (functionptr) Java_java_lang_VMThrowable_fillInStackTrace,
186 (functionptr) Java_java_lang_VMThrowable_getStackTrace,
188 (functionptr) Java_java_lang_reflect_Constructor_getModifiers,
189 (functionptr) Java_java_lang_reflect_Constructor_constructNative,
191 (functionptr) Java_java_lang_reflect_Field_getModifiers,
192 (functionptr) Java_java_lang_reflect_Field_getType,
193 (functionptr) Java_java_lang_reflect_Field_get,
194 (functionptr) Java_java_lang_reflect_Field_getBoolean,
195 (functionptr) Java_java_lang_reflect_Field_getByte,
196 (functionptr) Java_java_lang_reflect_Field_getChar,
197 (functionptr) Java_java_lang_reflect_Field_getShort,
198 (functionptr) Java_java_lang_reflect_Field_getInt,
199 (functionptr) Java_java_lang_reflect_Field_getLong,
200 (functionptr) Java_java_lang_reflect_Field_getFloat,
201 (functionptr) Java_java_lang_reflect_Field_getDouble,
202 (functionptr) Java_java_lang_reflect_Field_set,
203 (functionptr) Java_java_lang_reflect_Field_setBoolean,
204 (functionptr) Java_java_lang_reflect_Field_setByte,
205 (functionptr) Java_java_lang_reflect_Field_setChar,
206 (functionptr) Java_java_lang_reflect_Field_setShort,
207 (functionptr) Java_java_lang_reflect_Field_setInt,
208 (functionptr) Java_java_lang_reflect_Field_setLong,
209 (functionptr) Java_java_lang_reflect_Field_setFloat,
210 (functionptr) Java_java_lang_reflect_Field_setDouble,
212 (functionptr) Java_java_lang_reflect_Proxy_getProxyClass0,
213 (functionptr) Java_java_lang_reflect_Proxy_getProxyData0,
214 (functionptr) Java_java_lang_reflect_Proxy_generateProxyClass0,
216 (functionptr) Java_java_lang_reflect_Method_getModifiers,
217 (functionptr) Java_java_lang_reflect_Method_getReturnType,
218 (functionptr) Java_java_lang_reflect_Method_getParameterTypes,
219 (functionptr) Java_java_lang_reflect_Method_getExceptionTypes,
220 (functionptr) Java_java_lang_reflect_Method_invokeNative,
222 (functionptr) Java_java_security_VMAccessController_getStack,
225 #endif /* defined(STATIC_CLASSPATH) */
228 /************* use classinfo structure as java.lang.Class object **************/
230 void use_class_as_object(classinfo *c)
232 if (!c->classvftbl) {
233 /* is the class loaded */
235 /* if (!class_load(c)) */
236 /* throw_exception_exit(); */
237 log_text("use_class_as_object: class_load should not happen");
241 /* is the class linked */
244 throw_exception_exit();
246 assert(class_java_lang_Class);
248 c->header.vftbl = class_java_lang_Class->vftbl;
249 c->classvftbl = true;
254 /************************** tables for methods ********************************/
259 #ifdef STATIC_CLASSPATH
260 #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref))
262 /* table for fast string comparison */
263 static nativecompref nativecomptable[NATIVETABLESIZE];
265 /* string comparsion table initialized */
266 static bool nativecompdone = false;
270 /* XXX don't define this in a header file!!! */
272 static struct nativeCall nativeCalls[] =
274 #include "nativecalls.inc"
277 #define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall))
279 struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE];
282 /* global variables ***********************************************************/
284 static hashtable library_hash;
285 static lt_dlhandle mainhandle;
288 /* native_loadclasses **********************************************************
290 Load classes required for native methods.
292 *******************************************************************************/
294 bool native_init(void)
296 #if !defined(STATIC_CLASSPATH)
299 /* We need to access the dummy native table, not only to remove a warning */
300 /* but to be sure that the table is not optimized away (gcc does this */
303 p = &dummynativetable;
305 /* initialize libltdl */
308 /* XXX how can we throw an exception here? */
309 log_text(lt_dlerror());
314 /* get the handle for the main program */
316 if (!(mainhandle = lt_dlopen(NULL)))
319 /* initialize library hashtable, 10 entries should be enough */
321 init_hashtable(&library_hash, 10);
325 /* everything's ok */
331 /* native_library_hash_add *****************************************************
333 Adds an entry to the native library hashtable.
335 *******************************************************************************/
337 void native_library_hash_add(utf *filename, java_objectheader *loader,
340 library_hash_loader_entry *le;
341 library_hash_name_entry *ne; /* library name */
342 u4 key; /* hashkey */
343 u4 slot; /* slot in hashtable */
346 key = (u4) (ptrint) loader; /* we use the classinfo pointer */
347 slot = key & (library_hash.size - 1);
348 le = library_hash.ptr[slot];
350 /* search external hash chain for the entry */
353 if (le->loader == loader)
356 le = le->hashlink; /* next element in external chain */
359 /* no loader found? create a new entry */
362 le = NEW(library_hash_loader_entry);
367 /* insert entry into hashtable */
369 le->hashlink = (library_hash_loader_entry *) library_hash.ptr[slot];
370 library_hash.ptr[slot] = le;
372 /* update number of hashtable-entries */
374 library_hash.entries++;
378 /* search for library name */
383 if (ne->name->blength == filename->blength) {
384 for (i = 0; i < (u4) filename->blength; i++)
385 if (ne->name->text[i] != filename->text[i])
388 /* entry found in hashtable */
394 ne = ne->hashlink; /* next element in external chain */
397 /* not found? add the library name to the classloader */
399 ne = NEW(library_hash_name_entry);
404 /* insert entry into external chain */
406 ne->hashlink = le->namelink;
410 /* check for hashtable size */
412 if (library_hash.entries > (library_hash.size * 2)) {
414 /* reorganization of hashtable, average length of
415 the external chains is approx. 2 */
417 hashtable newhash; /* the new hashtable */
419 /* create new hashtable, double the size */
421 init_hashtable(&newhash, library_hash.size * 2);
422 newhash.entries = library_hash.entries;
424 /* transfer elements to new hashtable */
426 for (i = 0; i < library_hash.size; i++) {
427 le = (library_hash_loader_entry *) library_hash.ptr[i];
430 library_hash_loader_entry *nextl = le->hashlink;
431 u4 newslot = ((u4) (ptrint) le) & (newhash.size - 1);
434 (library_hash_loader_entry *) newhash.ptr[newslot];
436 newhash.ptr[newslot] = le;
442 /* dispose old table */
444 MFREE(library_hash.ptr, void *, library_hash.size);
446 library_hash = newhash;
451 /*********************** Function: native_findfunction *************************
453 Looks up a method (must have the same class name, method name, descriptor
454 and 'static'ness) and returns a function pointer to it.
455 Returns: function pointer or NULL (if there is no such method)
457 Remark: For faster operation, the names/descriptors are converted from C
458 strings to Unicode the first time this function is called.
460 *******************************************************************************/
462 functionptr native_findfunction(utf *cname, utf *mname,
463 utf *desc, bool isstatic)
465 #ifdef STATIC_CLASSPATH
467 /* entry of table for fast string comparison */
468 struct nativecompref *n;
469 /* for warning message if no function is found */
473 isstatic = isstatic ? true : false;
475 if (!nativecompdone) {
476 for (i = 0; i < NATIVETABLESIZE; i++) {
477 nativecomptable[i].classname =
478 utf_new_char(nativetable[i].classname);
479 nativecomptable[i].methodname =
480 utf_new_char(nativetable[i].methodname);
481 nativecomptable[i].descriptor =
482 utf_new_char(nativetable[i].descriptor);
483 nativecomptable[i].isstatic =
484 nativetable[i].isstatic;
485 nativecomptable[i].func =
488 nativecompdone = true;
493 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
495 buffer = MNEW(char, buffer_len);
497 strcpy(buffer, "searching matching function in native table:");
498 utf_sprint(buffer+strlen(buffer), mname);
499 strcpy(buffer+strlen(buffer), ": ");
500 utf_sprint(buffer+strlen(buffer), desc);
501 strcpy(buffer+strlen(buffer), " for class ");
502 utf_sprint(buffer+strlen(buffer), cname);
506 MFREE(buffer, char, buffer_len);
509 for (i = 0; i < NATIVETABLESIZE; i++) {
510 n = &(nativecomptable[i]);
512 if (cname == n->classname && mname == n->methodname &&
513 desc == n->descriptor && isstatic == n->isstatic)
517 if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch");
521 utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
523 buffer = MNEW(char, buffer_len);
525 strcpy(buffer, "comparing with:");
526 utf_sprint(buffer+strlen(buffer), n->methodname);
527 strcpy (buffer+strlen(buffer), ": ");
528 utf_sprint(buffer+strlen(buffer), n->descriptor);
529 strcpy(buffer+strlen(buffer), " for class ");
530 utf_sprint(buffer+strlen(buffer), n->classname);
534 MFREE(buffer, char, buffer_len);
541 /* no function was found, display warning */
544 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
546 buffer = MNEW(char, buffer_len);
548 strcpy(buffer, "warning: native function ");
549 utf_sprint(buffer + strlen(buffer), mname);
550 strcpy(buffer + strlen(buffer), ": ");
551 utf_sprint(buffer + strlen(buffer), desc);
552 strcpy(buffer + strlen(buffer), " not found in class ");
553 utf_sprint(buffer + strlen(buffer), cname);
557 MFREE(buffer, char, buffer_len);
561 /* keep compiler happy */
564 /* dynamic classpath */
570 /* native_make_overloaded_function *********************************************
574 *******************************************************************************/
576 #if !defined(STATIC_CLASSPATH)
577 static char *native_make_overloaded_function(char *name, utf *desc)
584 utf_ptr = desc->text;
585 namelen = strlen("__");
587 /* calculate additional length */
589 while ((c = utf_nextu2(&utf_ptr)) != ')') {
606 while (utf_nextu2(&utf_ptr) != ';')
618 /* reallocate memory */
622 DMREALLOC(name, char, i, namelen);
624 utf_ptr = desc->text;
629 while ((c = utf_nextu2(&utf_ptr)) != ')') {
647 while ((c = utf_nextu2(&utf_ptr)) != ';')
648 if (((c >= 'a') && (c <= 'z')) ||
649 ((c >= 'A') && (c <= 'Z')) ||
650 ((c >= '0') && (c <= '9')))
672 /* native_resolve_function *****************************************************
674 Resolves a native function, maybe from a dynamic library.
676 *******************************************************************************/
678 functionptr native_resolve_function(methodinfo *m)
686 library_hash_loader_entry *le;
687 library_hash_name_entry *ne;
688 u4 key; /* hashkey */
689 u4 slot; /* slot in hashtable */
693 /* calculate length of native function name */
695 namelen = strlen("Java_") + utf_strlen(m->class->name) + strlen("_") +
696 utf_strlen(m->name) + strlen("0");
698 /* check for underscores in class name */
700 utf_ptr = m->class->name->text;
701 utf_endptr = UTF_END(m->class->name);
703 while (utf_ptr < utf_endptr)
704 if (utf_nextu2(&utf_ptr) == '_')
707 /* check for underscores in method name */
709 utf_ptr = m->name->text;
710 utf_endptr = UTF_END(m->name);
712 while (utf_ptr < utf_endptr)
713 if (utf_nextu2(&utf_ptr) == '_')
716 /* allocate memory */
718 dumpsize = dump_size();
720 name = DMNEW(char, namelen);
723 /* generate name of native functions */
725 strcpy(name, "Java_");
728 utf_ptr = m->class->name->text;
729 utf_endptr = UTF_END(m->class->name);
731 for (; utf_ptr < utf_endptr; utf_ptr++, i++) {
734 /* escape sequence for '_' is '_1' */
739 /* replace '/' with '_' */
745 /* seperator between class and method */
749 utf_ptr = m->name->text;
750 utf_endptr = UTF_END(m->name);
752 for (; utf_ptr < utf_endptr; utf_ptr++, i++) {
755 /* escape sequence for '_' is '_1' */
766 /* try to find the native function symbol in the main program */
768 if (!(sym = lt_dlsym(mainhandle, name))) {
769 /* we didn't find the symbol yet, try to resolve an overloaded */
770 /* function (having the types in it's name) */
772 name = native_make_overloaded_function(name, m->descriptor);
774 /* try to find the overloaded symbol */
776 sym = lt_dlsym(mainhandle, name);
779 /* if symbol not found, check the library hash entries of the classloader */
780 /* of the methods's class */
783 key = (u4) (ptrint) m->class->classloader;
784 slot = key & (library_hash.size - 1);
785 le = library_hash.ptr[slot];
790 sym = lt_dlsym(ne->handle, name);
793 name = native_make_overloaded_function(name, m->descriptor);
794 sym = lt_dlsym(ne->handle, name);
801 /* no symbol found? throw exception */
805 new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
810 dump_release(dumpsize);
812 return (functionptr) (ptrint) sym;
814 #endif /* !defined(STATIC_CLASSPATH) */
817 /****************** function class_findfield_approx ****************************
819 searches in 'classinfo'-structure for a field with the
822 *******************************************************************************/
824 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
828 for (i = 0; i < c->fieldscount; i++) {
829 /* compare field names */
830 if ((c->fields[i].name == name))
831 return &(c->fields[i]);
834 /* field was not found, raise exception */
835 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
841 s4 class_findfield_index_approx(classinfo *c, utf *name)
845 for (i = 0; i < c->fieldscount; i++) {
846 /* compare field names */
847 if ((c->fields[i].name == name))
851 /* field was not found, raise exception */
852 *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
858 /* native_new_and_init *********************************************************
860 Creates a new object on the heap and calls the initializer.
861 Returns the object pointer or NULL if memory is exhausted.
863 *******************************************************************************/
865 java_objectheader *native_new_and_init(classinfo *c)
868 java_objectheader *o;
871 return *exceptionptr;
880 /* find initializer */
882 m = class_findmethod(c, utf_init, utf_void__void);
884 /* initializer not found */
889 /* call initializer */
891 asm_calljavafunction(m, o, NULL, NULL, NULL);
897 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
900 java_objectheader *o;
903 return *exceptionptr;
912 /* find initializer */
914 m = class_resolveclassmethod(c,
916 utf_java_lang_String__void,
920 /* initializer not found */
925 /* call initializer */
927 asm_calljavafunction(m, o, s, NULL, NULL);
933 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
936 java_objectheader *o;
939 return *exceptionptr;
948 /* find initializer */
950 m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true);
952 /* initializer not found */
957 /* call initializer */
959 asm_calljavafunction(m, o, (void *) (ptrint) i, NULL, NULL);
965 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
968 java_objectheader *o;
971 return *exceptionptr;
980 /* find initializer */
982 m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void);
984 /* initializer not found */
989 /* call initializer */
991 asm_calljavafunction(m, o, t, NULL, NULL);
997 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1001 /* XXX this kind of copying does not work (in the general
1002 * case). The interface tables would have to be copied, too. I
1003 * don't see why we should make a copy anyway. -Edwin
1005 *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1006 memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1007 memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1012 /******************************************************************************************
1014 creates method signature (excluding return type) from array of
1015 class-objects representing the parameters of the method
1017 *******************************************************************************************/
1020 utf *create_methodsig(java_objectarray* types, char *retType)
1022 char *buffer; /* buffer for building the desciptor */
1023 char *pos; /* current position in buffer */
1024 utf *result; /* the method signature */
1025 u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1028 if (!types) return NULL;
1030 /* determine required buffer-size */
1031 for (i = 0; i < types->header.size; i++) {
1032 classinfo *c = (classinfo *) types->data[i];
1033 buffer_size = buffer_size + c->name->blength + 2;
1036 if (retType) buffer_size += strlen(retType);
1038 /* allocate buffer */
1039 buffer = MNEW(char, buffer_size);
1042 /* method-desciptor starts with parenthesis */
1045 for (i = 0; i < types->header.size; i++) {
1048 /* current argument */
1049 classinfo *c = (classinfo *) types->data[i];
1051 /* current position in utf-text */
1052 char *utf_ptr = c->name->text;
1054 /* determine type of argument */
1055 if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1057 for (utf_ptr--; utf_ptr < UTF_END(c->name); utf_ptr++) {
1058 *pos++ = *utf_ptr; /* copy text */
1062 /* check for primitive types */
1063 for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1064 char *utf_pos = utf_ptr - 1;
1065 char *primitive = primitivetype_table[j].wrapname;
1068 while (utf_pos < UTF_END(c->name)) {
1069 if (*utf_pos++ != *primitive++) goto nomatch;
1072 /* primitive type found */
1073 *pos++ = primitivetype_table[j].typesig;
1080 /* no primitive type and no arrayclass, so must be object */
1084 for (utf_ptr--; utf_ptr < UTF_END(c->name); utf_ptr++) {
1098 for (i = 0; i < strlen(retType); i++) {
1099 *pos++ = retType[i];
1103 /* create utf-string */
1104 result = utf_new(buffer, (pos - buffer));
1105 MFREE(buffer, char, buffer_size);
1111 /* get_parametertypes **********************************************************
1113 Use the descriptor of a method to generate a java/lang/Class array
1114 which contains the classes of the parametertypes of the method.
1116 *******************************************************************************/
1118 java_objectarray *get_parametertypes(methodinfo *m)
1121 typedesc *paramtypes;
1123 java_objectarray *result;
1128 /* is the descriptor fully parsed? */
1130 if (!m->parseddesc->params)
1131 if (!descriptor_params_from_paramtypes(md, m->flags))
1134 paramtypes = md->paramtypes;
1135 paramcount = md->paramcount;
1137 /* skip `this' pointer */
1139 if (!(m->flags & ACC_STATIC)) {
1144 /* create class-array */
1146 result = builtin_anewarray(paramcount, class_java_lang_Class);
1150 for (i = 0; i < paramcount; i++) {
1151 if (!resolve_class_from_typedesc(¶mtypes[i], false,
1152 (classinfo **) &result->data[i]))
1155 use_class_as_object((classinfo *) result->data[i]);
1162 /* get_exceptiontypes **********************************************************
1164 get the exceptions which can be thrown by a method
1166 *******************************************************************************/
1168 java_objectarray* get_exceptiontypes(methodinfo *m)
1172 java_objectarray *result;
1175 excount = m->thrownexceptionscount;
1177 /* create class-array */
1178 assert(class_java_lang_Class);
1180 result = builtin_anewarray(excount, class_java_lang_Class);
1182 for (i = 0; i < excount; i++) {
1183 if (!resolve_classref_or_classinfo(NULL,m->thrownexceptions[i],resolveEager,false,&cls))
1184 return NULL; /* exception */
1185 use_class_as_object(cls);
1186 result->data[i] = (java_objectheader *)cls;
1193 /******************************************************************************************
1195 get the returntype class of a method
1197 *******************************************************************************************/
1199 classinfo *get_returntype(methodinfo *m)
1203 if (!resolve_class_from_typedesc(&(m->parseddesc->returntype),false,&cls))
1204 return NULL; /* exception */
1206 use_class_as_object(cls);
1211 /*****************************************************************************/
1212 /*****************************************************************************/
1215 /*--------------------------------------------------------*/
1216 void printNativeCall(nativeCall nc) {
1219 printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1220 for (i=0; i<nc.methCnt; i++) {
1221 printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1223 for (j=0; j<nc.callCnt[i]; j++) {
1224 printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1225 nc.methods[i].methodCalls[j].classname,
1226 nc.methods[i].methodCalls[j].methodname,
1227 nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1230 printf("-+++++--------------------\n");fflush(stdout);
1233 /*--------------------------------------------------------*/
1234 void printCompNativeCall(nativeCompCall nc) {
1236 printf("printCompNativeCall BEGIN\n");fflush(stdout);
1237 printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1238 utf_display(nc.classname); fflush(stdout);
1240 for (i=0; i<nc.methCnt; i++) {
1241 printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1242 utf_display(nc.methods[i].methodname); fflush(stdout);
1243 utf_display(nc.methods[i].descriptor);fflush(stdout);
1244 printf("\n");fflush(stdout);
1246 for (j=0; j<nc.callCnt[i]; j++) {
1247 printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1248 utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1249 utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1250 utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1251 printf("\n");fflush(stdout);
1254 printf("---------------------\n");fflush(stdout);
1258 /*--------------------------------------------------------*/
1259 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d )
1272 /*--------------------------------------------------------*/
1273 nativeCall* findNativeClassCalls(char *aclassname ) {
1276 for (i=0;i<NATIVECALLSSIZE; i++) {
1277 /* convert table to utf later to speed up search */
1278 if (strcmp(nativeCalls[i].classname, aclassname) == 0)
1279 return &nativeCalls[i];
1284 /*--------------------------------------------------------*/
1285 /*--------------------------------------------------------*/
1286 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1290 ncc->classname = utf_new_char(nc.classname);
1291 ncc->methCnt = nc.methCnt;
1293 for (i=0; i<nc.methCnt; i++) {
1294 ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1295 ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1296 ncc->callCnt[i] = nc.callCnt[i];
1298 for (j=0; j<nc.callCnt[i]; j++) {
1300 ncc->methods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname);
1302 if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1303 ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1304 ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1307 ncc->methods[i].methodCalls[j].methodname = NULL;
1308 ncc->methods[i].methodCalls[j].descriptor = NULL;
1316 /*--------------------------------------------------------*/
1318 bool natcall2utf(bool natcallcompdone) {
1321 if (natcallcompdone)
1324 for (i=0;i<NATIVECALLSSIZE; i++) {
1325 utfNativeCall (nativeCalls[i], &nativeCompCalls[i]);
1332 * These are local overrides for various environment variables in Emacs.
1333 * Please do not remove this and leave it at the end of the file, where
1334 * Emacs will automagically detect them.
1335 * ---------------------------------------------------------------------
1338 * indent-tabs-mode: t