- forgot to include generated header files for dummynativetable
[cacao.git] / src / native / native.c
1 /* src/native/native.c - table of native functions
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28             Roman Obermaisser
29             Andreas Krall
30
31    Changes: Christian Thalinger
32
33    $Id: native.c 2465 2005-05-13 00:02:01Z twisti $
34
35 */
36
37
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <time.h>
41 #include <math.h>
42 #include <string.h>
43 #include <assert.h>
44 #include <sys/time.h>
45 #include <utime.h>
46
47 /* Include files for IO functions */
48
49 #include <fcntl.h>
50 #include <dirent.h>
51 #include <sys/types.h>
52 #ifdef _OSF_SOURCE 
53 #include <sys/mode.h>
54 #endif
55 #include <sys/stat.h>
56
57 #include "config.h"
58 #include "cacao/cacao.h"
59 #include "mm/memory.h"
60 #include "native/jni.h"
61 #include "native/native.h"
62 #include "native/include/java_lang_Throwable.h"
63 #include "toolbox/logging.h"
64 #include "vm/builtin.h"
65 #include "vm/exceptions.h"
66 #include "vm/global.h"
67 #include "vm/loader.h"
68 #include "vm/options.h"
69 #include "vm/stringlocal.h"
70 #include "vm/tables.h"
71 #include "vm/jit/asmpart.h"
72 #include "vm/jit/jit.h"
73 #include "vm/resolve.h"
74
75
76 /* include table of native functions ******************************************/
77
78 #include "native/include/java_lang_Cloneable.h"
79 #include "native/include/java_util_Properties.h"
80 #include "native/include/java_io_InputStream.h"
81 #include "native/include/java_io_PrintStream.h"
82
83 #include "native/include/gnu_classpath_VMStackWalker.h"
84 #include "native/include/gnu_classpath_VMSystemProperties.h"
85 #include "native/include/java_lang_Class.h"
86 #include "native/include/java_lang_Object.h"
87 #include "native/include/java_lang_VMClass.h"
88 #include "native/include/java_lang_VMClassLoader.h"
89 #include "native/include/java_lang_VMObject.h"
90 #include "native/include/java_lang_VMRuntime.h"
91 #include "native/include/java_lang_VMString.h"
92 #include "native/include/java_lang_VMSystem.h"
93 #include "native/include/java_lang_VMThread.h"
94 #include "native/include/java_lang_VMThrowable.h"
95 #include "native/include/java_lang_reflect_Constructor.h"
96 #include "native/include/java_lang_reflect_Field.h"
97 #include "native/include/java_lang_reflect_Proxy.h"
98 #include "native/include/java_lang_reflect_Method.h"
99
100 #if defined(STATIC_CLASSPATH)
101
102 #include "native/nativetable.inc"
103
104 #else /* defined(STATIC_CLASSPATH) */
105
106 /* Ensure that symbols for functions implemented within CACAO are used and    */
107 /* exported to dlopen.                                                        */
108
109 static functionptr dummynativetable[] = {
110         (functionptr) Java_gnu_classpath_VMStackWalker_getClassContext,
111
112         (functionptr) Java_gnu_classpath_VMSystemProperties_preInit,
113
114         (functionptr) Java_java_lang_VMClass_isInstance,
115         (functionptr) Java_java_lang_VMClass_isAssignableFrom,
116         (functionptr) Java_java_lang_VMClass_isInterface,
117         (functionptr) Java_java_lang_VMClass_isPrimitive,
118         (functionptr) Java_java_lang_VMClass_getName,
119         (functionptr) Java_java_lang_VMClass_getSuperclass,
120         (functionptr) Java_java_lang_VMClass_getInterfaces,
121         (functionptr) Java_java_lang_VMClass_getComponentType,
122         (functionptr) Java_java_lang_VMClass_getModifiers,
123         (functionptr) Java_java_lang_VMClass_getDeclaringClass,
124         (functionptr) Java_java_lang_VMClass_getDeclaredClasses,
125         (functionptr) Java_java_lang_VMClass_getDeclaredFields,
126         (functionptr) Java_java_lang_VMClass_getDeclaredMethods,
127         (functionptr) Java_java_lang_VMClass_getDeclaredConstructors,
128         (functionptr) Java_java_lang_VMClass_getClassLoader,
129         (functionptr) Java_java_lang_VMClass_forName,
130         (functionptr) Java_java_lang_VMClass_isArray,
131         (functionptr) Java_java_lang_VMClass_initialize,
132         (functionptr) Java_java_lang_VMClass_loadArrayClass,
133         (functionptr) Java_java_lang_VMClass_throwException,
134
135         (functionptr) Java_java_lang_VMClassLoader_defineClass,
136         (functionptr) Java_java_lang_VMClassLoader_resolveClass,
137         (functionptr) Java_java_lang_VMClassLoader_loadClass,
138         (functionptr) Java_java_lang_VMClassLoader_getPrimitiveClass,
139         (functionptr) Java_java_lang_VMClassLoader_nativeGetResources,
140
141         (functionptr) Java_java_lang_VMObject_getClass,
142         (functionptr) Java_java_lang_VMObject_clone,
143         (functionptr) Java_java_lang_VMObject_notify,
144         (functionptr) Java_java_lang_VMObject_notifyAll,
145         (functionptr) Java_java_lang_VMObject_wait,
146
147         (functionptr) Java_java_lang_VMRuntime_availableProcessors,
148         (functionptr) Java_java_lang_VMRuntime_freeMemory,
149         (functionptr) Java_java_lang_VMRuntime_totalMemory,
150         (functionptr) Java_java_lang_VMRuntime_maxMemory,
151         (functionptr) Java_java_lang_VMRuntime_gc,
152         (functionptr) Java_java_lang_VMRuntime_runFinalization,
153         (functionptr) Java_java_lang_VMRuntime_runFinalizationForExit,
154         (functionptr) Java_java_lang_VMRuntime_traceInstructions,
155         (functionptr) Java_java_lang_VMRuntime_traceMethodCalls,
156         (functionptr) Java_java_lang_VMRuntime_runFinalizersOnExit,
157         (functionptr) Java_java_lang_VMRuntime_exit,
158         (functionptr) Java_java_lang_VMRuntime_nativeLoad,
159         (functionptr) Java_java_lang_VMRuntime_mapLibraryName,
160
161         (functionptr) Java_java_lang_VMString_intern,
162
163         (functionptr) Java_java_lang_VMSystem_arraycopy,
164         (functionptr) Java_java_lang_VMSystem_identityHashCode,
165
166         (functionptr) Java_java_lang_VMThread_start,
167         (functionptr) Java_java_lang_VMThread_interrupt,
168         (functionptr) Java_java_lang_VMThread_isInterrupted,
169         (functionptr) Java_java_lang_VMThread_suspend,
170         (functionptr) Java_java_lang_VMThread_resume,
171         (functionptr) Java_java_lang_VMThread_nativeSetPriority,
172         (functionptr) Java_java_lang_VMThread_nativeStop,
173         (functionptr) Java_java_lang_VMThread_currentThread,
174         (functionptr) Java_java_lang_VMThread_yield,
175         (functionptr) Java_java_lang_VMThread_interrupted,
176         (functionptr) Java_java_lang_VMThread_holdsLock,
177
178         (functionptr) Java_java_lang_VMThrowable_fillInStackTrace,
179         (functionptr) Java_java_lang_VMThrowable_getStackTrace,
180
181         (functionptr) Java_java_lang_reflect_Constructor_getModifiers,
182         (functionptr) Java_java_lang_reflect_Constructor_constructNative,
183
184         (functionptr) Java_java_lang_reflect_Field_getModifiers,
185         (functionptr) Java_java_lang_reflect_Field_getType,
186         (functionptr) Java_java_lang_reflect_Field_get,
187         (functionptr) Java_java_lang_reflect_Field_getBoolean,
188         (functionptr) Java_java_lang_reflect_Field_getByte,
189         (functionptr) Java_java_lang_reflect_Field_getChar,
190         (functionptr) Java_java_lang_reflect_Field_getShort,
191         (functionptr) Java_java_lang_reflect_Field_getInt,
192         (functionptr) Java_java_lang_reflect_Field_getLong,
193         (functionptr) Java_java_lang_reflect_Field_getFloat,
194         (functionptr) Java_java_lang_reflect_Field_getDouble,
195         (functionptr) Java_java_lang_reflect_Field_set,
196         (functionptr) Java_java_lang_reflect_Field_setBoolean,
197         (functionptr) Java_java_lang_reflect_Field_setByte,
198         (functionptr) Java_java_lang_reflect_Field_setChar,
199         (functionptr) Java_java_lang_reflect_Field_setShort,
200         (functionptr) Java_java_lang_reflect_Field_setInt,
201         (functionptr) Java_java_lang_reflect_Field_setLong,
202         (functionptr) Java_java_lang_reflect_Field_setFloat,
203         (functionptr) Java_java_lang_reflect_Field_setDouble,
204
205         (functionptr) Java_java_lang_reflect_Proxy_getProxyClass0,
206         (functionptr) Java_java_lang_reflect_Proxy_getProxyData0,
207         (functionptr) Java_java_lang_reflect_Proxy_generateProxyClass0,
208
209         (functionptr) Java_java_lang_reflect_Method_getModifiers,
210         (functionptr) Java_java_lang_reflect_Method_getReturnType,
211         (functionptr) Java_java_lang_reflect_Method_getParameterTypes,
212         (functionptr) Java_java_lang_reflect_Method_getExceptionTypes,
213         (functionptr) Java_java_lang_reflect_Method_invokeNative,
214 };
215
216 #endif /* defined(STATIC_CLASSPATH) */
217
218
219 /************* use classinfo structure as java.lang.Class object **************/
220
221 void use_class_as_object(classinfo *c) 
222 {
223         if (!c->classvftbl) {
224                 /* is the class loaded */
225                 if (!c->loaded) {
226 /*                      if (!class_load(c)) */
227 /*                              throw_exception_exit(); */
228                         log_text("use_class_as_object: class_load should not happen");
229                         assert(0);
230                 }
231
232                 /* is the class linked */
233                 if (!c->linked)
234                         if (!link_class(c))
235                                 throw_exception_exit();
236
237                 assert(class_java_lang_Class);
238
239                 c->header.vftbl = class_java_lang_Class->vftbl;
240                 c->classvftbl = true;
241         }
242 }
243
244
245 /************************** tables for methods ********************************/
246
247 #undef JOWENN_DEBUG
248 #undef JOWENN_DEBUG1
249
250 #ifdef STATIC_CLASSPATH
251 #define NATIVETABLESIZE  (sizeof(nativetable)/sizeof(struct nativeref))
252
253 /* table for fast string comparison */
254 static nativecompref nativecomptable[NATIVETABLESIZE];
255
256 /* string comparsion table initialized */
257 static bool nativecompdone = false;
258 #endif
259
260
261 /* XXX don't define this in a header file!!! */
262
263 static struct nativeCall nativeCalls[] =
264 {
265 #include "nativecalls.inc"
266 };
267
268 #define NATIVECALLSSIZE    (sizeof(nativeCalls) / sizeof(struct nativeCall))
269
270 struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE];
271
272
273 /* native_loadclasses **********************************************************
274
275    Load classes required for native methods.
276
277 *******************************************************************************/
278
279 bool native_init(void)
280 {
281 #if !defined(STATIC_CLASSPATH)
282         void *p;
283
284         /* We need to access the dummy native table, not only to remove a warning */
285         /* but to be sure that the table is not optimized away (gcc does this     */
286         /* since 3.4).                                                            */
287         p = &dummynativetable;
288 #endif
289
290         /* everything's ok */
291
292         return true;
293 }
294
295
296 /*********************** Function: native_findfunction *************************
297
298         Looks up a method (must have the same class name, method name, descriptor
299         and 'static'ness) and returns a function pointer to it.
300         Returns: function pointer or NULL (if there is no such method)
301
302         Remark: For faster operation, the names/descriptors are converted from C
303                 strings to Unicode the first time this function is called.
304
305 *******************************************************************************/
306
307 functionptr native_findfunction(utf *cname, utf *mname, 
308                                                                 utf *desc, bool isstatic)
309 {
310 #ifdef STATIC_CLASSPATH
311         int i;
312         /* entry of table for fast string comparison */
313         struct nativecompref *n;
314         /* for warning message if no function is found */
315         char *buffer;                   
316         int buffer_len;
317
318         isstatic = isstatic ? true : false;
319         
320         if (!nativecompdone) {
321                 for (i = 0; i < NATIVETABLESIZE; i++) {
322                         nativecomptable[i].classname  = 
323                                 utf_new_char(nativetable[i].classname);
324                         nativecomptable[i].methodname = 
325                                 utf_new_char(nativetable[i].methodname);
326                         nativecomptable[i].descriptor = 
327                                 utf_new_char(nativetable[i].descriptor);
328                         nativecomptable[i].isstatic   = 
329                                 nativetable[i].isstatic;
330                         nativecomptable[i].func       = 
331                                 nativetable[i].func;
332                 }
333                 nativecompdone = true;
334         }
335
336 #ifdef JOWENN_DEBUG
337         buffer_len = 
338                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
339         
340         buffer = MNEW(char, buffer_len);
341
342         strcpy(buffer, "searching matching function in native table:");
343         utf_sprint(buffer+strlen(buffer), mname);
344         strcpy(buffer+strlen(buffer), ": ");
345         utf_sprint(buffer+strlen(buffer), desc);
346         strcpy(buffer+strlen(buffer), " for class ");
347         utf_sprint(buffer+strlen(buffer), cname);
348
349         log_text(buffer);       
350
351         MFREE(buffer, char, buffer_len);
352 #endif
353                 
354         for (i = 0; i < NATIVETABLESIZE; i++) {
355                 n = &(nativecomptable[i]);
356
357                 if (cname == n->classname && mname == n->methodname &&
358                     desc == n->descriptor && isstatic == n->isstatic)
359                         return n->func;
360 #ifdef JOWENN_DEBUG
361                         else {
362                                 if (cname == n->classname && mname == n->methodname )  log_text("static and descriptor mismatch");
363                         
364                                 else {
365                                         buffer_len = 
366                                           utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
367         
368                                         buffer = MNEW(char, buffer_len);
369
370                                         strcpy(buffer, "comparing with:");
371                                         utf_sprint(buffer+strlen(buffer), n->methodname);
372                                         strcpy (buffer+strlen(buffer), ": ");
373                                         utf_sprint(buffer+strlen(buffer), n->descriptor);
374                                         strcpy(buffer+strlen(buffer), " for class ");
375                                         utf_sprint(buffer+strlen(buffer), n->classname);
376
377                                         log_text(buffer);       
378
379                                         MFREE(buffer, char, buffer_len);
380                                 }
381                         } 
382 #endif
383         }
384
385                 
386         /* no function was found, display warning */
387
388         buffer_len = 
389                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
390
391         buffer = MNEW(char, buffer_len);
392
393         strcpy(buffer, "warning: native function ");
394         utf_sprint(buffer + strlen(buffer), mname);
395         strcpy(buffer + strlen(buffer), ": ");
396         utf_sprint(buffer + strlen(buffer), desc);
397         strcpy(buffer + strlen(buffer), " not found in class ");
398         utf_sprint(buffer + strlen(buffer), cname);
399
400         log_text(buffer);       
401
402         MFREE(buffer, char, buffer_len);
403
404 /*      exit(1); */
405
406         /* keep compiler happy */
407         return NULL;
408 #else
409 /* dynamic classpath */
410   return 0;
411 #endif
412 }
413
414
415 /****************** function class_findfield_approx ****************************
416         
417         searches in 'classinfo'-structure for a field with the
418         specified name
419
420 *******************************************************************************/
421  
422 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
423 {
424         s4 i;
425
426         for (i = 0; i < c->fieldscount; i++) {
427                 /* compare field names */
428                 if ((c->fields[i].name == name))
429                         return &(c->fields[i]);
430         }
431
432         /* field was not found, raise exception */      
433         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
434
435         return NULL;
436 }
437
438
439 s4 class_findfield_index_approx(classinfo *c, utf *name)
440 {
441         s4 i;
442
443         for (i = 0; i < c->fieldscount; i++) {
444                 /* compare field names */
445                 if ((c->fields[i].name == name))
446                         return i;
447         }
448
449         /* field was not found, raise exception */      
450         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
451
452         return -1;
453 }
454
455
456 /* native_new_and_init *********************************************************
457
458    Creates a new object on the heap and calls the initializer.
459    Returns the object pointer or NULL if memory is exhausted.
460                         
461 *******************************************************************************/
462
463 java_objectheader *native_new_and_init(classinfo *c)
464 {
465         methodinfo *m;
466         java_objectheader *o;
467
468         if (!c)
469                 return *exceptionptr;
470
471         /* create object */
472
473         o = builtin_new(c);
474         
475         if (!o)
476                 return NULL;
477
478         /* find initializer */
479
480         m = class_findmethod(c, utf_init, utf_void__void);
481                                                       
482         /* initializer not found */
483
484         if (!m)
485                 return o;
486
487         /* call initializer */
488
489         asm_calljavafunction(m, o, NULL, NULL, NULL);
490
491         return o;
492 }
493
494
495 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
496 {
497         methodinfo *m;
498         java_objectheader *o;
499
500         if (!c)
501                 return *exceptionptr;
502
503         /* create object */
504
505         o = builtin_new(c);
506
507         if (!o)
508                 return NULL;
509
510         /* find initializer */
511
512         m = class_resolveclassmethod(c,
513                                                                  utf_init,
514                                                                  utf_java_lang_String__void,
515                                                                  NULL,
516                                                                  true);
517
518         /* initializer not found */
519
520         if (!m)
521                 return NULL;
522
523         /* call initializer */
524
525         asm_calljavafunction(m, o, s, NULL, NULL);
526
527         return o;
528 }
529
530
531 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
532 {
533         methodinfo *m;
534         java_objectheader *o;
535
536         if (!c)
537                 return *exceptionptr;
538
539         /* create object */
540
541         o = builtin_new(c);
542         
543         if (!o)
544                 return NULL;
545
546         /* find initializer */
547
548         m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true);
549
550         /* initializer not found  */
551
552         if (!m)
553                 return NULL;
554
555         /* call initializer */
556
557         asm_calljavafunction(m, o, (void *) (ptrint) i, NULL, NULL);
558
559         return o;
560 }
561
562
563 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
564 {
565         methodinfo *m;
566         java_objectheader *o;
567
568         if (!c)
569                 return *exceptionptr;
570
571         /* create object */
572
573         o = builtin_new(c);
574         
575         if (!o)
576                 return NULL;
577
578         /* find initializer */
579
580         m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void);
581                                                       
582         /* initializer not found */
583
584         if (!m)
585                 return NULL;
586
587         /* call initializer */
588
589         asm_calljavafunction(m, o, t, NULL, NULL);
590
591         return o;
592 }
593
594
595 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
596 {
597     *dest = src;
598 #if 0
599     /* XXX this kind of copying does not work (in the general
600      * case). The interface tables would have to be copied, too. I
601      * don't see why we should make a copy anyway. -Edwin
602      */
603         *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
604         memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
605         memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
606 #endif
607 }
608
609
610 /******************************************************************************************                                                                                                             
611
612         creates method signature (excluding return type) from array of 
613         class-objects representing the parameters of the method 
614
615 *******************************************************************************************/
616
617
618 utf *create_methodsig(java_objectarray* types, char *retType)
619 {
620     char *buffer;       /* buffer for building the desciptor */
621     char *pos;          /* current position in buffer */
622     utf *result;        /* the method signature */
623     u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
624     u4 i, j;
625  
626     if (!types) return NULL;
627
628     /* determine required buffer-size */    
629     for (i = 0; i < types->header.size; i++) {
630                 classinfo *c = (classinfo *) types->data[i];
631                 buffer_size  = buffer_size + c->name->blength + 2;
632     }
633
634     if (retType) buffer_size += strlen(retType);
635
636     /* allocate buffer */
637     buffer = MNEW(char, buffer_size);
638     pos    = buffer;
639     
640     /* method-desciptor starts with parenthesis */
641     *pos++ = '(';
642
643     for (i = 0; i < types->header.size; i++) {
644                 char ch;           
645
646                 /* current argument */
647             classinfo *c = (classinfo *) types->data[i];
648
649             /* current position in utf-text */
650             char *utf_ptr = c->name->text; 
651             
652             /* determine type of argument */
653             if ((ch = utf_nextu2(&utf_ptr)) == '[') {
654                 /* arrayclass */
655                 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
656                                 *pos++ = *utf_ptr; /* copy text */
657                         }
658
659             } else {            
660                         /* check for primitive types */
661                         for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
662                                 char *utf_pos   = utf_ptr - 1;
663                                 char *primitive = primitivetype_table[j].wrapname;
664
665                                 /* compare text */
666                                 while (utf_pos < utf_end(c->name)) {
667                                         if (*utf_pos++ != *primitive++) goto nomatch;
668                                 }
669
670                                 /* primitive type found */
671                                 *pos++ = primitivetype_table[j].typesig;
672                                 goto next_type;
673
674                         nomatch:
675                                 ;
676                         }
677
678                         /* no primitive type and no arrayclass, so must be object */
679                         *pos++ = 'L';
680
681                         /* copy text */
682                         for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
683                                 *pos++ = *utf_ptr;
684                         }
685
686                         *pos++ = ';';
687
688                 next_type:
689                         ;
690                 }  
691     }       
692
693     *pos++ = ')';
694
695     if (retType) {
696                 for (i = 0; i < strlen(retType); i++) {
697                         *pos++ = retType[i];
698                 }
699     }
700
701     /* create utf-string */
702     result = utf_new(buffer, (pos - buffer));
703     MFREE(buffer, char, buffer_size);
704
705     return result;
706 }
707
708
709 /* get_parametertypes **********************************************************
710
711    use the descriptor of a method to generate a java/lang/Class array
712    which contains the classes of the parametertypes of the method
713
714 *******************************************************************************/
715
716 java_objectarray* get_parametertypes(methodinfo *m) 
717 {
718     methoddesc *descr =  m->parseddesc;    /* method-descriptor */ 
719     java_objectarray* result;
720     int parametercount = descr->paramcount;
721     int i;
722
723     /* create class-array */
724         assert(class_java_lang_Class);
725
726     result = builtin_anewarray(parametercount, class_java_lang_Class);
727
728     /* get classes */
729     for (i = 0; i < parametercount; i++) {
730                 if (!resolve_class_from_typedesc(descr->paramtypes + i,false,
731                                         (classinfo **) (result->data + i)))
732                         return NULL; /* exception */
733                 use_class_as_object((classinfo*) result->data[i]);
734         }
735
736     return result;
737 }
738
739
740 /* get_exceptiontypes **********************************************************
741
742    get the exceptions which can be thrown by a method
743
744 *******************************************************************************/
745
746 java_objectarray* get_exceptiontypes(methodinfo *m)
747 {
748     u2 excount;
749     u2 i;
750     java_objectarray *result;
751         classinfo *cls;
752
753         excount = m->thrownexceptionscount;
754
755     /* create class-array */
756         assert(class_java_lang_Class);
757
758     result = builtin_anewarray(excount, class_java_lang_Class);
759
760     for (i = 0; i < excount; i++) {
761                 if (!resolve_classref_or_classinfo(NULL,m->thrownexceptions[i],resolveEager,false,&cls))
762                         return NULL; /* exception */
763                 use_class_as_object(cls);
764                 result->data[i] = (java_objectheader *)cls;
765     }
766
767     return result;
768 }
769
770
771 /******************************************************************************************
772
773         get the returntype class of a method
774
775 *******************************************************************************************/
776
777 classinfo *get_returntype(methodinfo *m) 
778 {
779         classinfo *cls;
780
781         if (!resolve_class_from_typedesc(&(m->parseddesc->returntype),false,&cls))
782                 return NULL; /* exception */
783
784         use_class_as_object(cls);
785         return cls;
786 }
787
788
789 /*****************************************************************************/
790 /*****************************************************************************/
791
792
793 /*--------------------------------------------------------*/
794 void printNativeCall(nativeCall nc) {
795   int i,j;
796
797   printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
798   for (i=0; i<nc.methCnt; i++) {  
799       printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
800
801     for (j=0; j<nc.callCnt[i]; j++) {  
802         printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
803         nc.methods[i].methodCalls[j].classname, 
804         nc.methods[i].methodCalls[j].methodname, 
805         nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
806       }
807     }
808   printf("-+++++--------------------\n");fflush(stdout);
809 }
810
811 /*--------------------------------------------------------*/
812 void printCompNativeCall(nativeCompCall nc) {
813   int i,j;
814   printf("printCompNativeCall BEGIN\n");fflush(stdout); 
815   printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
816   utf_display(nc.classname); fflush(stdout);
817   
818   for (i=0; i<nc.methCnt; i++) {  
819     printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
820     utf_display(nc.methods[i].methodname); fflush(stdout);
821     utf_display(nc.methods[i].descriptor);fflush(stdout);
822     printf("\n");fflush(stdout);
823
824     for (j=0; j<nc.callCnt[i]; j++) {  
825       printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
826         utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
827         utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
828         utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
829         printf("\n");fflush(stdout);
830       }
831     }
832 printf("---------------------\n");fflush(stdout);
833 }
834
835
836 /*--------------------------------------------------------*/
837 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d ) 
838 {
839     int i = 0;
840     int j = 0;
841     int cnt = 0;
842     classMeth mc;
843     mc.i_class = i;
844     mc.j_method = j;
845     mc.methCnt = cnt;
846
847     return mc;
848 }
849
850 /*--------------------------------------------------------*/
851 nativeCall* findNativeClassCalls(char *aclassname ) {
852 int i;
853
854 for (i=0;i<NATIVECALLSSIZE; i++) {
855    /* convert table to utf later to speed up search */ 
856    if (strcmp(nativeCalls[i].classname, aclassname) == 0) 
857         return &nativeCalls[i];
858    }
859
860 return NULL;
861 }
862 /*--------------------------------------------------------*/
863 /*--------------------------------------------------------*/
864 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
865   int i,j;
866
867
868   ncc->classname = utf_new_char(nc.classname); 
869   ncc->methCnt = nc.methCnt;
870   
871   for (i=0; i<nc.methCnt; i++) {  
872     ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
873     ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
874     ncc->callCnt[i] = nc.callCnt[i];
875
876     for (j=0; j<nc.callCnt[i]; j++) {  
877
878         ncc->methods[i].methodCalls[j].classname  = utf_new_char(nc.methods[i].methodCalls[j].classname);
879
880         if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
881           ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
882           ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
883           }
884         else {
885           ncc->methods[i].methodCalls[j].methodname = NULL;
886           ncc->methods[i].methodCalls[j].descriptor = NULL;
887           }
888       }
889     }
890 }
891
892
893
894 /*--------------------------------------------------------*/
895
896 bool natcall2utf(bool natcallcompdone) {
897 int i;
898
899 if (natcallcompdone) 
900         return true;
901
902 for (i=0;i<NATIVECALLSSIZE; i++) {
903    utfNativeCall  (nativeCalls[i], &nativeCompCalls[i]);  
904    }
905
906 return true;
907 }
908
909 /*--------------------------------------------------------*/
910
911
912 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo **start)
913 {
914         /* XXX platform dependend */
915
916         java_objectarray *tmpArray;
917         int i;
918         classinfo **current;
919         classinfo *c;
920         size_t size;
921
922         size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
923
924         /*printf("end %p, start %p, size %ld\n",end,start,size);*/
925
926         if (size > 0) {
927                 if (*start == class_java_lang_SecurityManager) {
928                         size--;
929                         start--;
930                 }
931         }
932
933         tmpArray = builtin_anewarray(size, class_java_lang_Class);
934
935         for(i = 0, current = start; i < size; i++, current--) {
936                 c = *current;
937                 /*              printf("%d\n",i);
938                 utf_display(c->name);*/
939                 use_class_as_object(c);
940                 tmpArray->data[i] = (java_objectheader *) c;
941         }
942
943         return tmpArray;
944 }
945
946
947 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start)
948 {
949         /* XXX platform dependend */
950
951         int i;
952         classinfo **current;
953         classinfo *c;
954         classinfo *privilegedAction;
955         size_t size;
956
957         size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
958
959         /*      log_text("builtin_asm_getclassloader");
960         printf("end %p, start %p, size %ld\n",end,start,size);*/
961
962         if (!class_java_lang_SecurityManager)
963                 if (!load_class_bootstrap(utf_new_char("java/lang/SecurityManager"),&class_java_lang_SecurityManager))
964                         return NULL;
965
966         if (size > 0) {
967                 if (*start == class_java_lang_SecurityManager) {
968                         size--;
969                         start--;
970                 }
971         }
972
973         if (!load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"),&privilegedAction))
974                 return NULL;
975
976         for(i = 0, current = start; i < size; i++, current--) {
977                 c = *current;
978
979                 if (c == privilegedAction)
980                         return NULL;
981
982                 if (c->classloader)
983                         return (java_lang_ClassLoader *) c->classloader;
984         }
985
986         return NULL;
987 }
988
989
990 /*
991  * These are local overrides for various environment variables in Emacs.
992  * Please do not remove this and leave it at the end of the file, where
993  * Emacs will automagically detect them.
994  * ---------------------------------------------------------------------
995  * Local variables:
996  * mode: c
997  * indent-tabs-mode: t
998  * c-basic-offset: 4
999  * tab-width: 4
1000  * End:
1001  */