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