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