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