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