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