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