nat/GtkLabelPeer.c has been removed
[cacao.git] / src / native / native.c
1 /* native.c - table of native functions
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
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    The .hh files created with the header file generator are all
32    included here as are the C functions implementing these methods.
33
34    $Id: native.c 1322 2004-07-17 12:29:18Z motse $
35
36 */
37
38
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <time.h>
42 #include <math.h>
43 #include <string.h>
44 #include <assert.h>
45 #include <sys/time.h>
46 #include <utime.h>
47
48 #include "config.h"
49 #include "global.h"
50 #include "options.h"
51 #include "jni.h"
52 #include "native.h"
53 #include "builtin.h"
54 #include "asmpart.h"
55 #include "tables.h"
56 #include "loader.h"
57 #include "jni.h"
58 #include "jit/jit.h"
59 #include "toolbox/logging.h"
60 #include "toolbox/memory.h"
61 #include "threads/thread.h"
62 #include "threads/threadio.h"
63 #include "threads/locks.h"
64 #include "nat/java_lang_VMClass.h"
65 #include "nat/java_lang_Throwable.h"
66
67 /* Include files for IO functions */
68
69 #include <fcntl.h>
70 #include <dirent.h>
71 #include <sys/types.h>
72 #ifdef _OSF_SOURCE 
73 #include <sys/mode.h>
74 #endif
75 #include <sys/stat.h>
76
77 #include "threads/threadio.h"
78
79 /* include table of native functions */
80
81 #include "nativetable.inc"
82
83
84 /* searchpath for classfiles */
85 char *classpath;
86
87 /* for java-string to char conversion */
88 #define MAXSTRINGSIZE 1000                          
89
90
91 /******************** systemclasses required for native methods ***************/
92
93 classinfo *class_java_lang_Class;
94 classinfo *class_java_lang_VMClass;
95 classinfo *class_java_lang_System;
96 classinfo *class_java_lang_ClassLoader;
97 classinfo *class_gnu_java_lang_SystemClassLoader;
98 classinfo *class_java_lang_SecurityManager;
99 classinfo *class_java_lang_Double;
100 classinfo *class_java_lang_Float;
101 classinfo *class_java_lang_Long;
102 classinfo *class_java_lang_Byte;
103 classinfo *class_java_lang_Short;
104 classinfo *class_java_lang_Boolean;
105 classinfo *class_java_lang_Void;
106 classinfo *class_java_lang_Character;
107 classinfo *class_java_lang_Integer;
108
109 methodinfo *method_vmclass_init;
110
111
112 /* system exception classes required in cacao */
113
114 classinfo *class_java_lang_Throwable;
115 classinfo *class_java_lang_Exception;
116 classinfo *class_java_lang_Error;
117
118
119 /* exception/error super class */
120
121 char *string_java_lang_Throwable =
122     "java/lang/Throwable";
123
124 char *string_java_lang_VMThrowable =
125     "java/lang/VMThrowable";
126
127
128 /* specify some exception strings for code generation */
129
130 char *string_java_lang_ArithmeticException =
131     "java/lang/ArithmeticException";
132
133 char *string_java_lang_ArithmeticException_message =
134     "/ by zero";
135
136 char *string_java_lang_ArrayIndexOutOfBoundsException =
137     "java/lang/ArrayIndexOutOfBoundsException";
138
139 char *string_java_lang_ArrayStoreException =
140     "java/lang/ArrayStoreException";
141
142 char *string_java_lang_ClassCastException =
143     "java/lang/ClassCastException";
144
145 char *string_java_lang_ClassNotFoundException =
146         "java/lang/ClassNotFoundException";
147
148 char *string_java_lang_CloneNotSupportedException =
149     "java/lang/CloneNotSupportedException";
150
151 char *string_java_lang_Exception =
152     "java/lang/Exception";
153
154 char *string_java_lang_IllegalArgumentException =
155     "java/lang/IllegalArgumentException";
156
157 char *string_java_lang_IllegalMonitorStateException =
158     "java/lang/IllegalMonitorStateException";
159
160 char *string_java_lang_NegativeArraySizeException =
161     "java/lang/NegativeArraySizeException";
162
163 char *string_java_lang_NoSuchFieldException =
164         "java/lang/NoSuchFieldException";
165
166 char *string_java_lang_NoSuchMethodException =
167         "java/lang/NoSuchMethodException";
168
169 char *string_java_lang_NullPointerException =
170     "java/lang/NullPointerException";
171
172
173 /* specify some error strings for code generation */
174
175 char *string_java_lang_AbstractMethodError =
176     "java/lang/AbstractMethodError";
177
178 char *string_java_lang_ClassCircularityError =
179     "java/lang/ClassCircularityError";
180
181 char *string_java_lang_ClassFormatError =
182     "java/lang/ClassFormatError";
183
184 char *string_java_lang_Error =
185     "java/lang/Error";
186
187 char *string_java_lang_ExceptionInInitializerError =
188     "java/lang/ExceptionInInitializerError";
189
190 char *string_java_lang_IncompatibleClassChangeError =
191     "java/lang/IncompatibleClassChangeError";
192
193 char *string_java_lang_InternalError =
194     "java/lang/InternalError";
195
196 char *string_java_lang_LinkageError =
197     "java/lang/LinkageError";
198
199 char *string_java_lang_NoClassDefFoundError =
200     "java/lang/NoClassDefFoundError";
201
202 char *string_java_lang_NoSuchFieldError =
203         "java/lang/NoSuchFieldError";
204
205 char *string_java_lang_NoSuchMethodError =
206         "java/lang/NoSuchMethodError";
207
208 char *string_java_lang_OutOfMemoryError =
209     "java/lang/OutOfMemoryError";
210
211 char *string_java_lang_VerifyError =
212     "java/lang/VerifyError";
213
214 char *string_java_lang_VirtualMachineError =
215     "java/lang/VirtualMachineError";
216
217
218 /* the system classloader object */
219 struct java_lang_ClassLoader *SystemClassLoader = NULL;
220
221 /* for raising exceptions from native methods */
222 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
223 java_objectheader* _exceptionptr = NULL;
224 #endif
225
226 /************* use classinfo structure as java.lang.Class object **************/
227
228 void use_class_as_object(classinfo *c) 
229 {
230         if (!c->classvftbl) {
231                 c->header.vftbl = class_java_lang_Class->vftbl;
232                 c->classvftbl = true;
233         }
234              
235 }
236
237
238 /*************************** include native methods ***************************/ 
239
240 #ifdef USE_GTK 
241 #include "nat/GdkGraphics.c"
242 #include "nat/GtkComponentPeer.c"
243 #include "nat/GdkPixbufDecoder.c"
244 #include "nat/GtkScrollPanePeer.c"
245 #include "nat/GtkFileDialogPeer.c"
246 #endif
247
248
249 /************************** tables for methods ********************************/
250
251 #undef JOWENN_DEBUG
252 #undef JOWENN_DEBUG1
253
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
262
263 /******************************************************************************/
264 /******************************************************************************/
265 #include "natcalls.h"
266
267 /* string call comparison table initialized */
268
269 /******************************************************************************/
270 /******************************************************************************/
271
272 /* init_system_exceptions *****************************************************
273
274    load, link and compile exceptions used in the system
275
276 *******************************************************************************/
277
278 void init_system_exceptions()
279 {
280         /* java/lang/Throwable */
281
282         class_java_lang_Throwable =
283                 class_new(utf_new_char(string_java_lang_Throwable));
284         class_load(class_java_lang_Throwable);
285         class_link(class_java_lang_Throwable);
286
287         /* java/lang/Exception */
288
289         class_java_lang_Exception =
290                 class_new(utf_new_char(string_java_lang_Exception));
291         class_load(class_java_lang_Exception);
292         class_link(class_java_lang_Exception);
293
294         /* java/lang/Error */
295
296         class_java_lang_Error =
297                 class_new(utf_new_char(string_java_lang_Error));
298         class_load(class_java_lang_Error);
299         class_link(class_java_lang_Error);
300 }
301
302
303 void compile_all_class_methods(classinfo *c)
304 {
305         s4 i;
306
307         for (i = 0; i < c->methodscount; i++) {
308                 (void) jit_compile(&(c->methods[i]));
309         }
310 }
311
312
313 static void throw_exception_exit_intern(bool doexit)
314 {
315         java_objectheader *xptr;
316         classinfo *c;
317         methodinfo *pss;
318
319         if (*exceptionptr) {
320                 xptr = *exceptionptr;
321
322                 /* clear exception, because we are calling jit code again */
323                 *exceptionptr = NULL;
324
325                 c = xptr->vftbl->class;
326
327                 pss = class_resolveclassmethod(c,
328                                                                            utf_new_char("printStackTrace"),
329                                                                            utf_new_char("()V"),
330                                                                            class_java_lang_Object,
331                                                                            false);
332
333                 /* print the stacktrace */
334                 if (pss) {
335                         asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
336
337                         /* this normally means, we are EXTREMLY out of memory, but may be
338                            any other exception */
339                         if (*exceptionptr) {
340                                 utf_fprint_classname(stderr, c->name);
341                                 fprintf(stderr, "\n");
342                         }
343
344                 } else {
345                         utf_fprint_classname(stderr, c->name);
346                         fprintf(stderr, ": printStackTrace()V not found!\n");
347                 }
348
349                 fflush(stderr);
350
351                 /* good bye! */
352                 if (doexit) {
353                         exit(1);
354                 }
355         }
356 }
357
358
359 void throw_exception()
360 {
361         throw_exception_exit_intern(false);
362 }
363
364
365 void throw_exception_exit()
366 {
367         throw_exception_exit_intern(true);
368 }
369
370
371 void throw_main_exception()
372 {
373         fprintf(stderr, "Exception in thread \"main\" ");
374         fflush(stderr);
375
376         throw_exception_exit_intern(false);
377 }
378
379
380 void throw_main_exception_exit()
381 {
382         fprintf(stderr, "Exception in thread \"main\" ");
383         fflush(stderr);
384
385         throw_exception_exit_intern(true);
386 }
387
388
389 void throw_cacao_exception_exit(char *exception, char *message)
390 {
391         s4 i;
392         char *tmp;
393         s4 len;
394
395         len = strlen(exception);
396         tmp = MNEW(char, len);
397         strncpy(tmp, exception, len);
398
399         /* convert to classname */
400
401         for (i = len - 1; i >= 0; i--) {
402                 if (tmp[i] == '/') tmp[i] = '.';
403         }
404
405         fprintf(stderr, "Exception in thread \"main\" %s", tmp);
406
407         MFREE(tmp, char, len);
408
409         if (strlen(message) > 0)
410                 fprintf(stderr, ": %s", message);
411
412         fprintf(stderr, "\n");
413         fflush(stderr);
414
415         /* good bye! */
416         exit(1);
417 }
418
419
420 #define CREATENEW_EXCEPTION(ex) \
421         java_objectheader *newEx; \
422         java_objectheader *oldexception=*exceptionptr;\
423         *exceptionptr=0;\
424         newEx=ex;\
425         *exceptionptr=oldexception;\
426         return newEx;
427
428 java_objectheader *new_exception(char *classname)
429 {
430         classinfo *c = class_new(utf_new_char(classname));
431
432         CREATENEW_EXCEPTION(native_new_and_init(c));
433 }
434
435 java_objectheader *new_exception_message(char *classname, char *message)
436 {
437         classinfo *c = class_new(utf_new_char(classname));
438
439         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new_char(message)));
440 }
441
442
443 java_objectheader *new_exception_throwable(char *classname, java_lang_Throwable *throwable)
444 {
445         classinfo *c = class_new(utf_new_char(classname));
446
447         CREATENEW_EXCEPTION(native_new_and_init_throwable(c, throwable));
448 }
449
450
451 java_objectheader *new_exception_utfmessage(char *classname, utf *message)
452 {
453         classinfo *c = class_new(utf_new_char(classname));
454
455         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new(message)));
456 }
457
458
459 java_objectheader *new_exception_javastring(char *classname, java_lang_String *message)
460 {
461         classinfo *c = class_new(utf_new_char(classname));
462
463         CREATENEW_EXCEPTION(native_new_and_init_string(c, message));
464 }
465
466
467 java_objectheader *new_exception_int(char *classname, s4 i)
468 {
469         classinfo *c = class_new(utf_new_char(classname));
470
471         CREATENEW_EXCEPTION(native_new_and_init_int(c, i));
472 }
473
474
475 /*********************** function: native_loadclasses **************************
476
477         load classes required for native methods        
478
479 *******************************************************************************/
480
481 void native_loadclasses()
482 {
483         static int classesLoaded = 0; /*temporary hack JoWenn*/
484
485         if (classesLoaded)
486                 return;
487
488         classesLoaded = 1;
489
490         class_java_lang_Cloneable =
491                 class_new(utf_new_char("java/lang/Cloneable"));
492         class_load(class_java_lang_Cloneable);
493         class_link(class_java_lang_Cloneable);
494
495         class_java_lang_Class =
496                 class_new(utf_new_char("java/lang/Class"));
497         class_load(class_java_lang_Class);
498         class_link(class_java_lang_Class);
499
500         class_java_lang_VMClass =
501                 class_new(utf_new_char("java/lang/VMClass"));
502         class_load(class_java_lang_VMClass);
503         class_link(class_java_lang_VMClass);
504
505         class_java_lang_ClassLoader =
506                 class_new(utf_new_char("java/lang/ClassLoader"));
507         class_load(class_java_lang_ClassLoader);
508         class_link(class_java_lang_ClassLoader);
509
510         /* load classes for wrapping primitive types */
511         class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
512         class_load(class_java_lang_Double);
513         class_link(class_java_lang_Double);
514
515         class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
516         class_load(class_java_lang_Float);
517         class_link(class_java_lang_Float);
518
519         class_java_lang_Character =     class_new(utf_new_char("java/lang/Character"));
520         class_load(class_java_lang_Character);
521         class_link(class_java_lang_Character);
522
523         class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
524         class_load(class_java_lang_Integer);
525         class_link(class_java_lang_Integer);
526
527         class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
528         class_load(class_java_lang_Long);
529         class_link(class_java_lang_Long);
530
531         class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
532         class_load(class_java_lang_Byte);
533         class_link(class_java_lang_Byte);
534
535         class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
536         class_load(class_java_lang_Short);
537         class_link(class_java_lang_Short);
538
539         class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
540         class_load(class_java_lang_Boolean);
541         class_link(class_java_lang_Boolean);
542
543         class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
544         class_load(class_java_lang_Void);
545         class_link(class_java_lang_Void);
546
547 }
548
549
550 /*****************************************************************************
551
552         create systemclassloader object and initialize instance fields  
553
554 ******************************************************************************/
555
556 void init_systemclassloader() 
557 {
558         log_text("init_systemclassloader");
559         if (!SystemClassLoader) {
560                 native_loadclasses();
561                 log_text("Initializing new system class loader");
562                 /* create object and call initializer */
563                 SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
564
565                 /* systemclassloader has no parent */
566                 SystemClassLoader->parent      = NULL;
567                 SystemClassLoader->initialized = true;
568         }
569         log_text("leaving system class loader");
570 }
571
572
573 /********************* function: native_setclasspath **************************/
574  
575 void native_setclasspath(char *path)
576 {
577         /* set searchpath for classfiles */
578         classpath = path;
579 }
580
581
582 /*********************** Function: native_findfunction *************************
583
584         Looks up a method (must have the same class name, method name, descriptor
585         and 'static'ness) and returns a function pointer to it.
586         Returns: function pointer or NULL (if there is no such method)
587
588         Remark: For faster operation, the names/descriptors are converted from C
589                 strings to Unicode the first time this function is called.
590
591 *******************************************************************************/
592
593 functionptr native_findfunction(utf *cname, utf *mname, 
594                                                                 utf *desc, bool isstatic)
595 {
596         int i;
597         /* entry of table for fast string comparison */
598         struct nativecompref *n;
599         /* for warning message if no function is found */
600         char *buffer;                   
601         int buffer_len;
602
603         isstatic = isstatic ? true : false;
604         
605         if (!nativecompdone) {
606                 for (i = 0; i < NATIVETABLESIZE; i++) {
607                         nativecomptable[i].classname  = 
608                                 utf_new_char(nativetable[i].classname);
609                         nativecomptable[i].methodname = 
610                                 utf_new_char(nativetable[i].methodname);
611                         nativecomptable[i].descriptor = 
612                                 utf_new_char(nativetable[i].descriptor);
613                         nativecomptable[i].isstatic   = 
614                                 nativetable[i].isstatic;
615                         nativecomptable[i].func       = 
616                                 nativetable[i].func;
617                 }
618                 nativecompdone = true;
619         }
620
621 #ifdef JOWENN_DEBUG
622         buffer_len = 
623                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
624         
625         buffer = MNEW(char, buffer_len);
626
627         strcpy(buffer, "searching matching function in native table:");
628         utf_sprint(buffer+strlen(buffer), mname);
629         strcpy(buffer+strlen(buffer), ": ");
630         utf_sprint(buffer+strlen(buffer), desc);
631         strcpy(buffer+strlen(buffer), " for class ");
632         utf_sprint(buffer+strlen(buffer), cname);
633
634         log_text(buffer);       
635
636         MFREE(buffer, char, buffer_len);
637 #endif
638                 
639         for (i = 0; i < NATIVETABLESIZE; i++) {
640                 n = &(nativecomptable[i]);
641
642                 if (cname == n->classname && mname == n->methodname &&
643                     desc == n->descriptor && isstatic == n->isstatic)
644                         return n->func;
645 #ifdef JOWENN_DEBUG
646                         else {
647                                 if (cname == n->classname && mname == n->methodname )  log_text("static and descriptor mismatch");
648                         
649                                 else {
650                                         buffer_len = 
651                                           utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
652         
653                                         buffer = MNEW(char, buffer_len);
654
655                                         strcpy(buffer, "comparing with:");
656                                         utf_sprint(buffer+strlen(buffer), n->methodname);
657                                         strcpy (buffer+strlen(buffer), ": ");
658                                         utf_sprint(buffer+strlen(buffer), n->descriptor);
659                                         strcpy(buffer+strlen(buffer), " for class ");
660                                         utf_sprint(buffer+strlen(buffer), n->classname);
661
662                                         log_text(buffer);       
663
664                                         MFREE(buffer, char, buffer_len);
665                                 }
666                         } 
667 #endif
668         }
669
670                 
671         /* no function was found, display warning */
672
673         buffer_len = 
674                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
675
676         buffer = MNEW(char, buffer_len);
677
678         strcpy(buffer, "warning: native function ");
679         utf_sprint(buffer + strlen(buffer), mname);
680         strcpy(buffer + strlen(buffer), ": ");
681         utf_sprint(buffer + strlen(buffer), desc);
682         strcpy(buffer + strlen(buffer), " not found in class ");
683         utf_sprint(buffer + strlen(buffer), cname);
684
685         log_text(buffer);       
686
687         MFREE(buffer, char, buffer_len);
688
689 /*      exit(1); */
690
691         /* keep compiler happy */
692         return NULL;
693 }
694
695
696 /********************** function: javastring_new *******************************
697
698         creates a new object of type java/lang/String with the text of 
699         the specified utf8-string
700
701         return: pointer to the string or NULL if memory is exhausted.   
702
703 *******************************************************************************/
704
705 java_lang_String *javastring_new(utf *u)
706 {
707         char *utf_ptr = u->text;        /* current utf character in utf string    */
708         int utflength = utf_strlen(u);  /* length of utf-string if uncompressed   */
709         java_lang_String *s;                /* result-string                          */
710         java_chararray *a;
711         s4 i;
712         
713         s = (java_lang_String *) builtin_new(class_java_lang_String);
714         a = builtin_newarray_char(utflength);
715
716         /* javastring or character-array could not be created */
717         if (!a || !s)
718                 return NULL;
719
720         /* decompress utf-string */
721         for (i = 0; i < utflength; i++)
722                 a->data[i] = utf_nextu2(&utf_ptr);
723         
724         /* set fields of the javastring-object */
725         s->value  = a;
726         s->offset = 0;
727         s->count  = utflength;
728
729         return s;
730 }
731
732
733 /********************** function: javastring_new_char **************************
734
735         creates a new java/lang/String object which contains the convertet
736         C-string passed via text.
737
738         return: the object pointer or NULL if memory is exhausted.
739
740 *******************************************************************************/
741
742 java_lang_String *javastring_new_char(char *text)
743 {
744         s4 i;
745         s4 len = strlen(text); /* length of the string */
746         java_lang_String *s;   /* result-string */
747         java_chararray *a;
748         
749         s = (java_lang_String *) builtin_new(class_java_lang_String);
750         a = builtin_newarray_char(len);
751
752         /* javastring or character-array could not be created */
753         if (!a || !s)
754                 return NULL;
755
756         /* copy text */
757         for (i = 0; i < len; i++)
758                 a->data[i] = text[i];
759         
760         /* set fields of the javastring-object */
761         s->value  = a;
762         s->offset = 0;
763         s->count  = len;
764
765         return s;
766 }
767
768
769 /************************* function javastring_tochar **************************
770
771         converts a Java string into a C string.
772         
773         return: pointer to C string
774         
775         Caution: every call of this function overwrites the previous string !!!
776         
777 *******************************************************************************/
778
779 static char stringbuffer[MAXSTRINGSIZE];
780
781 char *javastring_tochar(java_objectheader *so) 
782 {
783         java_lang_String *s = (java_lang_String *) so;
784         java_chararray *a;
785         s4 i;
786         
787         if (!s)
788                 return "";
789
790         a = s->value;
791
792         if (!a)
793                 return "";
794
795         if (s->count > MAXSTRINGSIZE)
796                 return "";
797
798         for (i = 0; i < s->count; i++)
799                 stringbuffer[i] = a->data[s->offset + i];
800
801         stringbuffer[i] = '\0';
802
803         return stringbuffer;
804 }
805
806
807 /****************** function class_findfield_approx ****************************
808         
809         searches in 'classinfo'-structure for a field with the
810         specified name
811
812 *******************************************************************************/
813  
814 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
815 {
816         s4 i;
817
818         for (i = 0; i < c->fieldscount; i++) {
819                 /* compare field names */
820                 if ((c->fields[i].name == name))
821                         return &(c->fields[i]);
822         }
823
824         /* field was not found, raise exception */      
825         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
826
827         return NULL;
828 }
829
830
831 s4 class_findfield_index_approx(classinfo *c, utf *name)
832 {
833         s4 i;
834
835         for (i = 0; i < c->fieldscount; i++) {
836                 /* compare field names */
837                 if ((c->fields[i].name == name))
838                         return i;
839         }
840
841         /* field was not found, raise exception */      
842         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
843
844         return -1;
845 }
846
847
848 /********************** function: native_new_and_init *************************
849
850         Creates a new object on the heap and calls the initializer.
851         Returns the object pointer or NULL if memory is exhausted.
852                         
853 *******************************************************************************/
854
855 java_objectheader *native_new_and_init(classinfo *c)
856 {
857         methodinfo *m;
858         java_objectheader *o;
859
860         if (!c)
861                 return *exceptionptr;
862
863         o = builtin_new(c);                 /* create object                      */
864         
865         if (!o)
866                 return NULL;
867
868         /* find initializer */
869
870         m = class_findmethod(c,
871                                                  utf_new_char("<init>"),
872                                                  utf_new_char("()V"));
873                                                       
874         if (!m) {                           /* initializer not found              */
875                 if (verbose) {
876                         char logtext[MAXLOGTEXT];
877                         sprintf(logtext, "Warning: class has no instance-initializer: ");
878                         utf_sprint_classname(logtext + strlen(logtext), c->name);
879                         log_text(logtext);
880                 }
881                 return o;
882         }
883
884         /* call initializer */
885
886         asm_calljavafunction(m, o, NULL, NULL, NULL);
887
888         return o;
889 }
890
891
892 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
893 {
894         methodinfo *m;
895         java_objectheader *o;
896
897         if (!c)
898                 return *exceptionptr;
899
900         o = builtin_new(c);          /* create object          */
901
902         if (!o)
903                 return NULL;
904
905         /* find initializer */
906
907         m = class_findmethod(c,
908                                                  utf_new_char("<init>"),
909                                                  utf_new_char("(Ljava/lang/String;)V"));
910                                                       
911         if (!m) {                                       /* initializer not found  */
912                 if (verbose) {
913                         char logtext[MAXLOGTEXT];
914                         sprintf(logtext, "Warning: class has no instance-initializer: ");
915                         utf_sprint_classname(logtext + strlen(logtext), c->name);
916                         log_text(logtext);
917                 }
918                 return o;
919         }
920
921         /* call initializer */
922
923         asm_calljavafunction(m, o, s, NULL, NULL);
924
925         return o;
926 }
927
928
929 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
930 {
931         methodinfo *m;
932         java_objectheader *o;
933
934         if (!c)
935                 return *exceptionptr;
936
937         o = builtin_new(c);          /* create object          */
938         
939         if (!o) return NULL;
940
941         /* find initializer */
942
943         m = class_findmethod(c,
944                                                  utf_new_char("<init>"),
945                                                  utf_new_char("(I)V"));
946                                                       
947         if (!m) {                                       /* initializer not found  */
948                 if (verbose) {
949                         char logtext[MAXLOGTEXT];
950                         sprintf(logtext, "Warning: class has no instance-initializer: ");
951                         utf_sprint_classname(logtext + strlen(logtext), c->name);
952                         log_text(logtext);
953                 }
954                 return o;
955         }
956
957         /* call initializer */
958
959 #if defined(__I386__) || defined(__POWERPC__)
960         asm_calljavafunction(m, o, (void *) i, NULL, NULL);
961 #else
962         asm_calljavafunction(m, o, (void *) (s8) i, NULL, NULL);
963 #endif
964
965         return o;
966 }
967
968
969 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
970 {
971         methodinfo *m;
972         java_objectheader *o;
973
974         if (!c)
975                 return *exceptionptr;
976
977         o = builtin_new(c);          /* create object          */
978         
979         if (!o) return NULL;
980
981         /* find initializer */
982
983         m = class_findmethod(c,
984                                                  utf_new_char("<init>"),
985                                                  utf_new_char("(Ljava/lang/Throwable;)V"));
986                                                       
987         if (!m) {                                       /* initializer not found  */
988                 if (verbose) {
989                         char logtext[MAXLOGTEXT];
990                         sprintf(logtext, "Warning: class has no instance-initializer: ");
991                         utf_sprint_classname(logtext + strlen(logtext), c->name);
992                         log_text(logtext);
993                 }
994                 return o;
995         }
996
997         /* call initializer */
998
999         asm_calljavafunction(m, o, t, NULL, NULL);
1000
1001         return o;
1002 }
1003
1004
1005 /******************** function: stringtable_update ****************************
1006
1007         traverses the javastring hashtable and sets the vftbl-entries of
1008         javastrings which were temporarily set to NULL, because 
1009         java.lang.Object was not yet loaded
1010
1011 *******************************************************************************/
1012  
1013 void stringtable_update ()
1014 {
1015         java_lang_String *js;   
1016         java_chararray *a;
1017         literalstring *s;       /* hashtable entry */
1018         int i;
1019
1020         for (i = 0; i < string_hash.size; i++) {
1021                 s = string_hash.ptr[i];
1022                 if (s) {
1023                         while (s) {
1024                                                                 
1025                                 js = (java_lang_String *) s->string;
1026                                 
1027                                 if (!js || !js->value) 
1028                                         /* error in hashtable found */
1029                                         panic("invalid literalstring in hashtable");
1030
1031                                 a = js->value;
1032
1033                                 if (!js->header.vftbl) 
1034                                         /* vftbl of javastring is NULL */ 
1035                                         js->header.vftbl = class_java_lang_String->vftbl;
1036
1037                                 if (!a->header.objheader.vftbl) 
1038                                         /* vftbl of character-array is NULL */ 
1039                                         a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
1040
1041                                 /* follow link in external hash chain */
1042                                 s = s->hashlink;
1043                         }       
1044                 }               
1045         }
1046 }
1047
1048
1049 /************************* function: u2_utflength ***************************
1050
1051         returns the utf length in bytes of a u2 array 
1052
1053 *****************************************************************************/
1054
1055 u4 u2_utflength(u2 *text, u4 u2_length)
1056 {
1057         u4 result_len =  0;  /* utf length in bytes  */
1058         u2 ch;               /* current unicode character */
1059         u4 len;
1060         
1061         for (len = 0; len < u2_length; len++) {
1062                 /* next unicode character */
1063                 ch = *text++;
1064           
1065                 /* determine bytes required to store unicode character as utf */
1066                 if (ch && (ch < 0x80)) 
1067                         result_len++;
1068                 else if (ch < 0x800)
1069                         result_len += 2;        
1070                 else 
1071                         result_len += 3;        
1072         }
1073
1074     return result_len;
1075 }
1076
1077
1078 /********************* function: utf_new_u2 ***********************************
1079
1080         make utf symbol from u2 array, 
1081         if isclassname is true '.' is replaced by '/'
1082
1083 *******************************************************************************/
1084
1085 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
1086 {
1087         char *buffer; /* memory buffer for  unicode characters */
1088         char *pos;    /* pointer to current position in buffer */
1089         u4 left;      /* unicode characters left */
1090         u4 buflength; /* utf length in bytes of the u2 array  */
1091         utf *result;  /* resulting utf-string */
1092         int i;          
1093
1094         /* determine utf length in bytes and allocate memory */
1095         /* printf("utf_new_u2: unicode_length=%d\n",unicode_length);            */
1096         buflength = u2_utflength(unicode_pos, unicode_length); 
1097         buffer    = MNEW(char, buflength);
1098  
1099         left = buflength;
1100         pos  = buffer;
1101
1102         for (i = 0; i++ < unicode_length; unicode_pos++) {
1103                 /* next unicode character */
1104                 u2 c = *unicode_pos;
1105                 
1106                 if ((c != 0) && (c < 0x80)) {
1107                         /* 1 character */       
1108                         left--;
1109                 if ((int) left < 0) break;
1110                         /* convert classname */
1111                         if (isclassname && c == '.')
1112                                 *pos++ = '/';
1113                         else
1114                                 *pos++ = (char) c;
1115
1116                 } else if (c < 0x800) {             
1117                         /* 2 characters */                              
1118                 unsigned char high = c >> 6;
1119                 unsigned char low  = c & 0x3F;
1120                         left = left - 2;
1121                 if ((int) left < 0) break;
1122                 *pos++ = high | 0xC0; 
1123                 *pos++ = low  | 0x80;     
1124
1125                 } else {         
1126                 /* 3 characters */                              
1127                 char low  = c & 0x3f;
1128                 char mid  = (c >> 6) & 0x3F;
1129                 char high = c >> 12;
1130                         left = left - 3;
1131                 if ((int) left < 0) break;
1132                 *pos++ = high | 0xE0; 
1133                 *pos++ = mid  | 0x80;  
1134                 *pos++ = low  | 0x80;   
1135                 }
1136         }
1137         
1138         /* insert utf-string into symbol-table */
1139         result = utf_new(buffer,buflength);
1140
1141         MFREE(buffer, char, buflength);
1142
1143         return result;
1144 }
1145
1146
1147 /********************* function: javastring_toutf *****************************
1148
1149         make utf symbol from javastring
1150
1151 *******************************************************************************/
1152
1153 utf *javastring_toutf(java_lang_String *string, bool isclassname)
1154 {
1155         java_lang_String *str = (java_lang_String *) string;
1156
1157 /*      printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
1158 /*      fflush(stdout); */
1159
1160         return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
1161 }
1162
1163
1164 /********************* function: literalstring_u2 *****************************
1165
1166     searches for the javastring with the specified u2-array in 
1167     the string hashtable, if there is no such string a new one is 
1168     created 
1169
1170     if copymode is true a copy of the u2-array is made
1171
1172 *******************************************************************************/
1173
1174 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
1175                                                                         bool copymode)
1176 {
1177     literalstring *s;                /* hashtable element */
1178     java_lang_String *js;            /* u2-array wrapped in javastring */
1179     java_chararray *stringdata;      /* copy of u2-array */      
1180         classinfo *c;
1181     u4 key;
1182     u4 slot;
1183     u2 i;
1184
1185 //#define DEBUG_LITERALSTRING_U2
1186 #ifdef DEBUG_LITERALSTRING_U2
1187     printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
1188         fflush(stdout);
1189 #endif
1190     
1191     /* find location in hashtable */
1192     key  = unicode_hashkey(a->data + offset, length);
1193     slot = key & (string_hash.size - 1);
1194     s    = string_hash.ptr[slot];
1195
1196     while (s) {
1197                 js = (java_lang_String *) s->string;
1198
1199                 if (length == js->count) {
1200                         /* compare text */
1201                         for (i = 0; i < length; i++) {
1202                                 if (a->data[offset + i] != js->value->data[i])
1203                                         goto nomatch;
1204                         }
1205
1206                         /* string already in hashtable, free memory */
1207                         if (!copymode)
1208                                 lit_mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
1209
1210 #ifdef DEBUG_LITERALSTRING_U2
1211                         printf("literalstring_u2: foundentry at %p\n", js);
1212                         utf_display(javastring_toutf(js, 0));
1213                         printf("\n\n");
1214                         fflush(stdout);
1215 #endif
1216                         return (java_objectheader *) js;
1217                 }
1218
1219         nomatch:
1220                 /* follow link in external hash chain */
1221                 s = s->hashlink;
1222     }
1223
1224     if (copymode) {
1225                 /* create copy of u2-array for new javastring */
1226                 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
1227                 stringdata = lit_mem_alloc(arraysize);
1228 /*              memcpy(stringdata, a, arraysize); */
1229                 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
1230                 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
1231
1232     } else {
1233                 stringdata = a;
1234         }
1235
1236     /* location in hashtable found, complete arrayheader */
1237     stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
1238     stringdata->header.size = length;
1239
1240         /* if we use eager loading, we have to check loaded String class */
1241         if (opt_eager) {
1242                 class_java_lang_String =
1243                         class_new_intern(utf_new_char("java/lang/String"));
1244
1245                 if (!class_load(class_java_lang_String))
1246                         return NULL;
1247
1248                 list_addfirst(&unlinkedclasses, class_java_lang_String);
1249         }
1250
1251     /* create new javastring */
1252     js = LNEW(java_lang_String);
1253         js->header.vftbl = class_java_lang_String->vftbl;
1254     js->value  = stringdata;
1255     js->offset = 0;
1256     js->count  = length;
1257
1258 #ifdef DEBUG_LITERALSTRING_U2
1259         printf("literalstring_u2: newly created at %p\n", js);
1260         utf_display(javastring_toutf(js, 0));
1261         printf("\n\n");
1262         fflush(stdout);
1263 #endif
1264                         
1265     /* create new literalstring */
1266     s = NEW(literalstring);
1267     s->hashlink = string_hash.ptr[slot];
1268     s->string   = (java_objectheader *) js;
1269     string_hash.ptr[slot] = s;
1270
1271     /* update number of hashtable entries */
1272     string_hash.entries++;
1273
1274     /* reorganization of hashtable */       
1275     if (string_hash.entries > (string_hash.size * 2)) {
1276                 /* reorganization of hashtable, average length of 
1277          the external chains is approx. 2                */  
1278
1279                 u4 i;
1280                 literalstring *s;
1281                 hashtable newhash; /* the new hashtable */
1282       
1283                 /* create new hashtable, double the size */
1284                 init_hashtable(&newhash, string_hash.size * 2);
1285                 newhash.entries = string_hash.entries;
1286       
1287                 /* transfer elements to new hashtable */
1288                 for (i = 0; i < string_hash.size; i++) {
1289                         s = string_hash.ptr[i];
1290                         while (s) {
1291                                 literalstring *nexts = s->hashlink;
1292                                 js   = (java_lang_String *) s->string;
1293                                 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
1294           
1295                                 s->hashlink = newhash.ptr[slot];
1296                                 newhash.ptr[slot] = s;
1297         
1298                                 /* follow link in external hash chain */  
1299                                 s = nexts;
1300                         }
1301                 }
1302         
1303                 /* dispose old table */ 
1304                 MFREE(string_hash.ptr, void*, string_hash.size);
1305                 string_hash = newhash;
1306     }
1307
1308     return (java_objectheader *) js;
1309 }
1310
1311
1312 /******************** Function: literalstring_new *****************************
1313
1314     creates a new javastring with the text of the utf-symbol
1315     and inserts it into the string hashtable
1316
1317 *******************************************************************************/
1318
1319 java_objectheader *literalstring_new(utf *u)
1320 {
1321     char *utf_ptr = u->text;         /* pointer to current unicode character in utf string */
1322     u4 utflength  = utf_strlen(u);   /* length of utf-string if uncompressed */
1323     java_chararray *a;               /* u2-array constructed from utf string */
1324     u4 i;
1325
1326     /* allocate memory */ 
1327     a = lit_mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1328
1329     /* convert utf-string to u2-array */
1330     for (i = 0; i < utflength; i++)
1331                 a->data[i] = utf_nextu2(&utf_ptr);
1332
1333     return literalstring_u2(a, utflength, 0, false);
1334 }
1335
1336
1337 /********************** function: literalstring_free **************************
1338
1339         removes a javastring from memory                       
1340
1341 ******************************************************************************/
1342
1343 void literalstring_free(java_objectheader* sobj)
1344 {
1345         java_lang_String *s = (java_lang_String *) sobj;
1346         java_chararray *a = s->value;
1347
1348         /* dispose memory of java.lang.String object */
1349         LFREE(s, java_lang_String);
1350
1351         /* dispose memory of java-characterarray */
1352         LFREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1353 }
1354
1355
1356 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
1357 {
1358     *dest = src;
1359 #if 0
1360     /* XXX this kind of copying does not work (in the general
1361      * case). The interface tables would have to be copied, too. I
1362      * don't see why we should make a copy anyway. -Edwin
1363      */
1364         *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1365         memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1366         memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1367 #endif
1368 }
1369
1370
1371 /******************************************************************************************                                                                                                             
1372
1373         creates method signature (excluding return type) from array of 
1374         class-objects representing the parameters of the method 
1375
1376 *******************************************************************************************/
1377
1378
1379 utf *create_methodsig(java_objectarray* types, char *retType)
1380 {
1381     char *buffer;       /* buffer for building the desciptor */
1382     char *pos;          /* current position in buffer */
1383     utf *result;        /* the method signature */
1384     u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1385     u4 i, j;
1386  
1387     if (!types) return NULL;
1388
1389     /* determine required buffer-size */    
1390     for (i = 0; i < types->header.size; i++) {
1391                 classinfo *c = (classinfo *) types->data[i];
1392                 buffer_size  = buffer_size + c->name->blength + 2;
1393     }
1394
1395     if (retType) buffer_size += strlen(retType);
1396
1397     /* allocate buffer */
1398     buffer = MNEW(u1, buffer_size);
1399     pos    = buffer;
1400     
1401     /* method-desciptor starts with parenthesis */
1402     *pos++ = '(';
1403
1404     for (i = 0; i < types->header.size; i++) {
1405                 char ch;           
1406
1407                 /* current argument */
1408             classinfo *c = (classinfo *) types->data[i];
1409
1410             /* current position in utf-text */
1411             char *utf_ptr = c->name->text; 
1412             
1413             /* determine type of argument */
1414             if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1415                 /* arrayclass */
1416                 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1417                                 *pos++ = *utf_ptr; /* copy text */
1418                         }
1419
1420             } else {            
1421                         /* check for primitive types */
1422                         for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1423                                 char *utf_pos   = utf_ptr - 1;
1424                                 char *primitive = primitivetype_table[j].wrapname;
1425
1426                                 /* compare text */
1427                                 while (utf_pos < utf_end(c->name)) {
1428                                         if (*utf_pos++ != *primitive++) goto nomatch;
1429                                 }
1430
1431                                 /* primitive type found */
1432                                 *pos++ = primitivetype_table[j].typesig;
1433                                 goto next_type;
1434
1435                         nomatch:
1436                                 ;
1437                         }
1438
1439                         /* no primitive type and no arrayclass, so must be object */
1440                         *pos++ = 'L';
1441
1442                         /* copy text */
1443                         for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1444                                 *pos++ = *utf_ptr;
1445                         }
1446
1447                         *pos++ = ';';
1448
1449                 next_type:
1450                         ;
1451                 }  
1452     }       
1453
1454     *pos++ = ')';
1455
1456     if (retType) {
1457                 for (i = 0; i < strlen(retType); i++) {
1458                         *pos++ = retType[i];
1459                 }
1460     }
1461
1462     /* create utf-string */
1463     result = utf_new(buffer, (pos - buffer));
1464     MFREE(buffer, u1, buffer_size);
1465
1466     return result;
1467 }
1468
1469
1470 /******************************************************************************************
1471
1472         retrieve the next argument or returntype from a descriptor
1473         and return the corresponding class 
1474
1475 *******************************************************************************************/
1476
1477 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1478 {
1479     classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1480                                          (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1481     if (!c)
1482         /* unknown type */
1483         panic("illegal descriptor");
1484
1485     if (skip) return NULL;
1486
1487     use_class_as_object(c);
1488     return c;
1489 }
1490
1491
1492 /* get_parametertypes **********************************************************
1493
1494    use the descriptor of a method to generate a java/lang/Class array
1495    which contains the classes of the parametertypes of the method
1496
1497 *******************************************************************************/
1498
1499 java_objectarray* get_parametertypes(methodinfo *m) 
1500 {
1501     utf  *descr    =  m->descriptor;    /* method-descriptor */ 
1502     char *utf_ptr  =  descr->text;      /* current position in utf-text */
1503     char *desc_end =  utf_end(descr);   /* points behind utf string     */
1504     java_objectarray* result;
1505     int parametercount = 0;
1506     int i;
1507
1508     /* skip '(' */
1509     utf_nextu2(&utf_ptr);
1510   
1511     /* determine number of parameters */
1512     while (*utf_ptr != ')') {
1513         get_type(&utf_ptr, desc_end, true);
1514                 parametercount++;
1515     }
1516
1517     /* create class-array */
1518     result = builtin_anewarray(parametercount, class_java_lang_Class);
1519
1520     utf_ptr = descr->text;
1521     utf_nextu2(&utf_ptr);
1522
1523     /* get returntype classes */
1524     for (i = 0; i < parametercount; i++)
1525             result->data[i] =
1526                         (java_objectheader *) get_type(&utf_ptr, desc_end, false);
1527
1528     return result;
1529 }
1530
1531
1532 /* get_exceptiontypes **********************************************************
1533
1534    get the exceptions which can be thrown by a method
1535
1536 *******************************************************************************/
1537
1538 java_objectarray* get_exceptiontypes(methodinfo *m) {
1539     u2 exccount=m->thrownexceptionscount;
1540     u2 i;
1541     java_objectarray *result;
1542     /* create class-array */
1543     result = builtin_anewarray(exccount, class_java_lang_Class);
1544     for (i=0;i<exccount;i++) {
1545         java_objectheader *oh=(java_objectheader*)(m->thrownexceptions[i]);
1546         use_class_as_object(oh);
1547         result->data[i]=oh;
1548     }
1549     return result;
1550 }
1551
1552
1553
1554
1555
1556 /******************************************************************************************
1557
1558         get the returntype class of a method
1559
1560 *******************************************************************************************/
1561
1562 classinfo *get_returntype(methodinfo *m) 
1563 {
1564         char *utf_ptr;   /* current position in utf-text */
1565         char *desc_end;  /* points behind utf string     */
1566         utf *desc = m->descriptor; /* method-descriptor  */
1567
1568         utf_ptr  = desc->text;
1569         desc_end = utf_end(desc);
1570
1571         /* ignore parametertypes */
1572         while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1573                 /* skip */ ;
1574
1575         return get_type(&utf_ptr,desc_end, false);
1576 }
1577
1578
1579 /*****************************************************************************/
1580 /*****************************************************************************/
1581
1582
1583 /*--------------------------------------------------------*/
1584 void printNativeCall(nativeCall nc) {
1585   int i,j;
1586
1587   printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1588   for (i=0; i<nc.methCnt; i++) {  
1589       printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1590
1591     for (j=0; j<nc.callCnt[i]; j++) {  
1592         printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1593         nc.methods[i].methodCalls[j].classname, 
1594         nc.methods[i].methodCalls[j].methodname, 
1595         nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1596       }
1597     }
1598   printf("-+++++--------------------\n");fflush(stdout);
1599 }
1600
1601 /*--------------------------------------------------------*/
1602 void printCompNativeCall(nativeCompCall nc) {
1603   int i,j;
1604   printf("printCompNativeCall BEGIN\n");fflush(stdout); 
1605   printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1606   utf_display(nc.classname); fflush(stdout);
1607   
1608   for (i=0; i<nc.methCnt; i++) {  
1609     printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1610     utf_display(nc.methods[i].methodname); fflush(stdout);
1611     utf_display(nc.methods[i].descriptor);fflush(stdout);
1612     printf("\n");fflush(stdout);
1613
1614     for (j=0; j<nc.callCnt[i]; j++) {  
1615       printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1616         utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1617         utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1618         utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1619         printf("\n");fflush(stdout);
1620       }
1621     }
1622 printf("---------------------\n");fflush(stdout);
1623 }
1624
1625
1626 /*--------------------------------------------------------*/
1627 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d ) 
1628 {
1629     int i = 0;
1630     int j = 0;
1631     int cnt = 0;
1632     classMeth mc;
1633     mc.i_class = i;
1634     mc.j_method = j;
1635     mc.methCnt = cnt;
1636
1637     return mc;
1638 }
1639
1640 /*--------------------------------------------------------*/
1641 nativeCall* findNativeClassCalls(char *aclassname ) {
1642 int i;
1643
1644 for (i=0;i<NATIVECALLSSIZE; i++) {
1645    /* convert table to utf later to speed up search */ 
1646    if (strcmp(nativeCalls[i].classname, aclassname) == 0) 
1647         return &nativeCalls[i];
1648    }
1649
1650 return NULL;
1651 }
1652 /*--------------------------------------------------------*/
1653 /*--------------------------------------------------------*/
1654 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1655   int i,j;
1656
1657
1658   ncc->classname = utf_new_char(nc.classname); 
1659   ncc->methCnt = nc.methCnt;
1660   
1661   for (i=0; i<nc.methCnt; i++) {  
1662     ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1663     ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1664     ncc->callCnt[i] = nc.callCnt[i];
1665
1666     for (j=0; j<nc.callCnt[i]; j++) {  
1667
1668         ncc->methods[i].methodCalls[j].classname  = utf_new_char(nc.methods[i].methodCalls[j].classname);
1669
1670         if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1671           ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1672           ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1673           }
1674         else {
1675           ncc->methods[i].methodCalls[j].methodname = NULL;
1676           ncc->methods[i].methodCalls[j].descriptor = NULL;
1677           }
1678       }
1679     }
1680 }
1681
1682
1683
1684 /*--------------------------------------------------------*/
1685
1686 bool natcall2utf(bool natcallcompdone) {
1687 int i;
1688
1689 if (natcallcompdone) 
1690         return true;
1691
1692 for (i=0;i<NATIVECALLSSIZE; i++) {
1693    utfNativeCall  (nativeCalls[i], &nativeCompCalls[i]);  
1694    }
1695
1696 return true;
1697 }
1698
1699 /*--------------------------------------------------------*/
1700
1701
1702 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end,classinfo **start)
1703 {
1704 #if defined(__GNUC__)
1705 #warning platform dependend
1706 #endif
1707         java_objectarray *tmpArray;
1708         int i;
1709         classinfo **current;
1710         classinfo *c;
1711         size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1712         /*printf("end %p, start %p, size %ld\n",end,start,size);*/
1713         if (!class_java_lang_Class)
1714                 class_java_lang_Class = class_new(utf_new_char ("java/lang/Class"));
1715         if (!class_java_lang_SecurityManager)
1716                 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1717         if (size>0) {
1718                 if (start==class_java_lang_SecurityManager) {
1719                         size--;
1720                         start--;
1721                 }
1722         }
1723         tmpArray=builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1724
1725         for(i=0,current=start;i<size;i++,current--) {
1726                 c=*current;
1727 /*              printf("%d\n",i);
1728                 utf_display(c->name);*/
1729                 use_class_as_object(c);
1730                 tmpArray->data[i]=c;
1731         }
1732         return tmpArray;
1733
1734 }
1735
1736 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end,classinfo **start)
1737 {
1738 #if defined(__GNUC__)
1739 #warning platform dependend
1740 #endif
1741         int i;
1742         classinfo **current;
1743         classinfo *c;
1744         classinfo *privilegedAction;
1745         size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1746 /*      log_text("builtin_asm_getclassloader");
1747         printf("end %p, start %p, size %ld\n",end,start,size);*/
1748
1749         if (!class_java_lang_SecurityManager)
1750                 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1751         if (size>0) {
1752                 if (start==class_java_lang_SecurityManager) {
1753                         size--;
1754                         start--;
1755                 }
1756         }
1757
1758         privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1759
1760         for(i=0,current=start;i<size;i++,current--) {
1761                 c=*current;
1762                 if (c==privilegedAction) return NULL;
1763                 if (c->classloader) return c->classloader;
1764         }
1765         return NULL;
1766
1767
1768
1769
1770 /*
1771         log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1772         init_systemclassloader();
1773
1774         return SystemClassLoader;*/
1775 }
1776
1777 /*
1778  * These are local overrides for various environment variables in Emacs.
1779  * Please do not remove this and leave it at the end of the file, where
1780  * Emacs will automagically detect them.
1781  * ---------------------------------------------------------------------
1782  * Local variables:
1783  * mode: c
1784  * indent-tabs-mode: t
1785  * c-basic-offset: 4
1786  * tab-width: 4
1787  * End:
1788  */