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