ifdef __GNUC__ #warnings for mips pro compiler
[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 1113 2004-06-02 10:31:09Z 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 #define CREATENEW_EXCEPTION(ex) \
530         java_objectheader *newEx; \
531         java_objectheader *oldexception=*exceptionptr;\
532         *exceptionptr=0;\
533         newEx=ex;\
534         *exceptionptr=oldexception;\
535         return newEx;
536
537 java_objectheader *new_exception(char *classname)
538 {
539         classinfo *c = class_new(utf_new_char(classname));
540
541         CREATENEW_EXCEPTION(native_new_and_init(c));
542 }
543
544 java_objectheader *new_exception_message(char *classname, char *message)
545 {
546         classinfo *c = class_new(utf_new_char(classname));
547
548         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new_char(message)));
549 }
550
551
552 java_objectheader *new_exception_throwable(char *classname, java_lang_Throwable *throwable)
553 {
554         classinfo *c = class_new(utf_new_char(classname));
555
556         CREATENEW_EXCEPTION(native_new_and_init_throwable(c, throwable));
557 }
558
559
560 java_objectheader *new_exception_utfmessage(char *classname, utf *message)
561 {
562         classinfo *c = class_new(utf_new_char(classname));
563
564         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new(message)));
565 }
566
567
568 java_objectheader *new_exception_javastring(char *classname, java_lang_String *message)
569 {
570         classinfo *c = class_new(utf_new_char(classname));
571
572         CREATENEW_EXCEPTION(native_new_and_init_string(c, message));
573 }
574
575
576 java_objectheader *new_exception_int(char *classname, s4 i)
577 {
578         classinfo *c = class_new(utf_new_char(classname));
579
580         CREATENEW_EXCEPTION(native_new_and_init_int(c, i));
581 }
582
583
584 /*********************** function: native_loadclasses **************************
585
586         load classes required for native methods        
587
588 *******************************************************************************/
589
590 void native_loadclasses()
591 {
592         static int classesLoaded = 0; /*temporary hack JoWenn*/
593
594         if (classesLoaded)
595                 return;
596
597         classesLoaded = 1;
598
599         class_java_lang_Cloneable =
600                 class_new(utf_new_char("java/lang/Cloneable"));
601         class_load(class_java_lang_Cloneable);
602         class_link(class_java_lang_Cloneable);
603
604         class_java_lang_Class =
605                 class_new(utf_new_char("java/lang/Class"));
606         class_load(class_java_lang_Class);
607         class_link(class_java_lang_Class);
608
609         class_java_lang_VMClass =
610                 class_new(utf_new_char("java/lang/VMClass"));
611         class_load(class_java_lang_VMClass);
612         class_link(class_java_lang_VMClass);
613
614         class_java_lang_ClassLoader =
615                 class_new(utf_new_char("java/lang/ClassLoader"));
616         class_load(class_java_lang_ClassLoader);
617         class_link(class_java_lang_ClassLoader);
618
619         /* load classes for wrapping primitive types */
620         class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
621         class_load(class_java_lang_Double);
622         class_link(class_java_lang_Double);
623
624         class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
625         class_load(class_java_lang_Float);
626         class_link(class_java_lang_Float);
627
628         class_java_lang_Character =     class_new(utf_new_char("java/lang/Character"));
629         class_load(class_java_lang_Character);
630         class_link(class_java_lang_Character);
631
632         class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
633         class_load(class_java_lang_Integer);
634         class_link(class_java_lang_Integer);
635
636         class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
637         class_load(class_java_lang_Long);
638         class_link(class_java_lang_Long);
639
640         class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
641         class_load(class_java_lang_Byte);
642         class_link(class_java_lang_Byte);
643
644         class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
645         class_load(class_java_lang_Short);
646         class_link(class_java_lang_Short);
647
648         class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
649         class_load(class_java_lang_Boolean);
650         class_link(class_java_lang_Boolean);
651
652         class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
653         class_load(class_java_lang_Void);
654         class_link(class_java_lang_Void);
655 }
656
657
658 /*****************************************************************************
659
660         create systemclassloader object and initialize instance fields  
661
662 ******************************************************************************/
663
664 void init_systemclassloader() 
665 {
666         log_text("init_systemclassloader");
667         if (!SystemClassLoader) {
668                 native_loadclasses();
669                 log_text("Initializing new system class loader");
670                 /* create object and call initializer */
671                 SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
672
673                 /* systemclassloader has no parent */
674                 SystemClassLoader->parent      = NULL;
675                 SystemClassLoader->initialized = true;
676         }
677         log_text("leaving system class loader");
678 }
679
680
681 /********************* function: native_setclasspath **************************/
682  
683 void native_setclasspath(char *path)
684 {
685         /* set searchpath for classfiles */
686         classpath = path;
687 }
688
689
690 /*********************** Function: native_findfunction *************************
691
692         Looks up a method (must have the same class name, method name, descriptor
693         and 'static'ness) and returns a function pointer to it.
694         Returns: function pointer or NULL (if there is no such method)
695
696         Remark: For faster operation, the names/descriptors are converted from C
697                 strings to Unicode the first time this function is called.
698
699 *******************************************************************************/
700
701 functionptr native_findfunction(utf *cname, utf *mname, 
702                                                                 utf *desc, bool isstatic)
703 {
704         int i;
705         /* entry of table for fast string comparison */
706         struct nativecompref *n;
707         /* for warning message if no function is found */
708         char *buffer;                   
709         int buffer_len;
710
711         isstatic = isstatic ? true : false;
712         
713         if (!nativecompdone) {
714                 for (i = 0; i < NATIVETABLESIZE; i++) {
715                         nativecomptable[i].classname  = 
716                                 utf_new_char(nativetable[i].classname);
717                         nativecomptable[i].methodname = 
718                                 utf_new_char(nativetable[i].methodname);
719                         nativecomptable[i].descriptor = 
720                                 utf_new_char(nativetable[i].descriptor);
721                         nativecomptable[i].isstatic   = 
722                                 nativetable[i].isstatic;
723                         nativecomptable[i].func       = 
724                                 nativetable[i].func;
725                 }
726                 nativecompdone = true;
727         }
728
729 #ifdef JOWENN_DEBUG
730         buffer_len = 
731                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
732         
733         buffer = MNEW(char, buffer_len);
734
735         strcpy(buffer, "searching matching function in native table:");
736         utf_sprint(buffer+strlen(buffer), mname);
737         strcpy(buffer+strlen(buffer), ": ");
738         utf_sprint(buffer+strlen(buffer), desc);
739         strcpy(buffer+strlen(buffer), " for class ");
740         utf_sprint(buffer+strlen(buffer), cname);
741
742         log_text(buffer);       
743
744         MFREE(buffer, char, buffer_len);
745 #endif
746                 
747         for (i = 0; i < NATIVETABLESIZE; i++) {
748                 n = &(nativecomptable[i]);
749
750                 if (cname == n->classname && mname == n->methodname &&
751                     desc == n->descriptor && isstatic == n->isstatic)
752                         return n->func;
753 #ifdef JOWENN_DEBUG
754                         else {
755                                 if (cname == n->classname && mname == n->methodname )  log_text("static and descriptor mismatch");
756                         
757                                 else {
758                                         buffer_len = 
759                                           utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
760         
761                                         buffer = MNEW(char, buffer_len);
762
763                                         strcpy(buffer, "comparing with:");
764                                         utf_sprint(buffer+strlen(buffer), n->methodname);
765                                         strcpy (buffer+strlen(buffer), ": ");
766                                         utf_sprint(buffer+strlen(buffer), n->descriptor);
767                                         strcpy(buffer+strlen(buffer), " for class ");
768                                         utf_sprint(buffer+strlen(buffer), n->classname);
769
770                                         log_text(buffer);       
771
772                                         MFREE(buffer, char, buffer_len);
773                                 }
774                         } 
775 #endif
776         }
777
778                 
779         /* no function was found, display warning */
780
781         buffer_len = 
782                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
783
784         buffer = MNEW(char, buffer_len);
785
786         strcpy(buffer, "warning: native function ");
787         utf_sprint(buffer + strlen(buffer), mname);
788         strcpy(buffer + strlen(buffer), ": ");
789         utf_sprint(buffer + strlen(buffer), desc);
790         strcpy(buffer + strlen(buffer), " not found in class ");
791         utf_sprint(buffer + strlen(buffer), cname);
792
793         log_text(buffer);       
794
795         MFREE(buffer, char, buffer_len);
796
797 /*      exit(1); */
798
799         /* keep compiler happy */
800         return NULL;
801 }
802
803
804 /********************** function: javastring_new *******************************
805
806         creates a new object of type java/lang/String with the text of 
807         the specified utf8-string
808
809         return: pointer to the string or NULL if memory is exhausted.   
810
811 *******************************************************************************/
812
813 java_lang_String *javastring_new(utf *u)
814 {
815         char *utf_ptr = u->text;        /* current utf character in utf string    */
816         int utflength = utf_strlen(u);  /* length of utf-string if uncompressed   */
817         java_lang_String *s;                /* result-string                          */
818         java_chararray *a;
819         s4 i;
820         
821         s = (java_lang_String *) builtin_new(class_java_lang_String);
822         a = builtin_newarray_char(utflength);
823
824         /* javastring or character-array could not be created */
825         if (!a || !s)
826                 return NULL;
827
828         /* decompress utf-string */
829         for (i = 0; i < utflength; i++)
830                 a->data[i] = utf_nextu2(&utf_ptr);
831         
832         /* set fields of the javastring-object */
833         s->value  = a;
834         s->offset = 0;
835         s->count  = utflength;
836
837         return s;
838 }
839
840
841 /********************** function: javastring_new_char **************************
842
843         creates a new java/lang/String object which contains the convertet
844         C-string passed via text.
845
846         return: the object pointer or NULL if memory is exhausted.
847
848 *******************************************************************************/
849
850 java_lang_String *javastring_new_char(char *text)
851 {
852         s4 i;
853         s4 len = strlen(text); /* length of the string */
854         java_lang_String *s;   /* result-string */
855         java_chararray *a;
856         
857         s = (java_lang_String *) builtin_new(class_java_lang_String);
858         a = builtin_newarray_char(len);
859
860         /* javastring or character-array could not be created */
861         if (!a || !s)
862                 return NULL;
863
864         /* copy text */
865         for (i = 0; i < len; i++)
866                 a->data[i] = text[i];
867         
868         /* set fields of the javastring-object */
869         s->value  = a;
870         s->offset = 0;
871         s->count  = len;
872
873         return s;
874 }
875
876
877 /************************* function javastring_tochar **************************
878
879         converts a Java string into a C string.
880         
881         return: pointer to C string
882         
883         Caution: every call of this function overwrites the previous string !!!
884         
885 *******************************************************************************/
886
887 static char stringbuffer[MAXSTRINGSIZE];
888
889 char *javastring_tochar(java_objectheader *so) 
890 {
891         java_lang_String *s = (java_lang_String *) so;
892         java_chararray *a;
893         s4 i;
894         
895         if (!s)
896                 return "";
897
898         a = s->value;
899
900         if (!a)
901                 return "";
902
903         if (s->count > MAXSTRINGSIZE)
904                 return "";
905
906         for (i = 0; i < s->count; i++)
907                 stringbuffer[i] = a->data[s->offset + i];
908
909         stringbuffer[i] = '\0';
910
911         return stringbuffer;
912 }
913
914
915 /****************** function class_findfield_approx ****************************
916         
917         searches in 'classinfo'-structure for a field with the
918         specified name
919
920 *******************************************************************************/
921  
922 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
923 {
924         s4 i;
925
926         for (i = 0; i < c->fieldscount; i++) {
927                 /* compare field names */
928                 if ((c->fields[i].name == name))
929                         return &(c->fields[i]);
930         }
931
932         /* field was not found, raise exception */      
933         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
934
935         return NULL;
936 }
937
938
939 s4 class_findfield_index_approx(classinfo *c, utf *name)
940 {
941         s4 i;
942
943         for (i = 0; i < c->fieldscount; i++) {
944                 /* compare field names */
945                 if ((c->fields[i].name == name))
946                         return i;
947         }
948
949         /* field was not found, raise exception */      
950         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
951
952         return -1;
953 }
954
955
956 /********************** function: native_new_and_init *************************
957
958         Creates a new object on the heap and calls the initializer.
959         Returns the object pointer or NULL if memory is exhausted.
960                         
961 *******************************************************************************/
962
963 java_objectheader *native_new_and_init(classinfo *c)
964 {
965         methodinfo *m;
966         java_objectheader *o;
967
968         if (!c)
969                 return *exceptionptr;
970
971         o = builtin_new(c);                 /* create object                      */
972         
973         if (!o)
974                 return NULL;
975
976         /* find initializer */
977
978         m = class_findmethod(c,
979                                                  utf_new_char("<init>"),
980                                                  utf_new_char("()V"));
981                                                       
982         if (!m) {                           /* initializer not found              */
983                 if (verbose) {
984                         char logtext[MAXLOGTEXT];
985                         sprintf(logtext, "Warning: class has no instance-initializer: ");
986                         utf_sprint_classname(logtext + strlen(logtext), c->name);
987                         log_text(logtext);
988                 }
989                 return o;
990         }
991
992         /* call initializer */
993
994         asm_calljavafunction(m, o, NULL, NULL, NULL);
995
996         return o;
997 }
998
999
1000 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
1001 {
1002         methodinfo *m;
1003         java_objectheader *o;
1004
1005         if (!c)
1006                 return *exceptionptr;
1007
1008         o = builtin_new(c);          /* create object          */
1009
1010         if (!o)
1011                 return NULL;
1012
1013         /* find initializer */
1014
1015         m = class_findmethod(c,
1016                                                  utf_new_char("<init>"),
1017                                                  utf_new_char("(Ljava/lang/String;)V"));
1018                                                       
1019         if (!m) {                                       /* initializer not found  */
1020                 if (verbose) {
1021                         char logtext[MAXLOGTEXT];
1022                         sprintf(logtext, "Warning: class has no instance-initializer: ");
1023                         utf_sprint_classname(logtext + strlen(logtext), c->name);
1024                         log_text(logtext);
1025                 }
1026                 return o;
1027         }
1028
1029         /* call initializer */
1030
1031         asm_calljavafunction(m, o, s, NULL, NULL);
1032
1033         return o;
1034 }
1035
1036
1037 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
1038 {
1039         methodinfo *m;
1040         java_objectheader *o;
1041
1042         if (!c)
1043                 return *exceptionptr;
1044
1045         o = builtin_new(c);          /* create object          */
1046         
1047         if (!o) return NULL;
1048
1049         /* find initializer */
1050
1051         m = class_findmethod(c,
1052                                                  utf_new_char("<init>"),
1053                                                  utf_new_char("(I)V"));
1054                                                       
1055         if (!m) {                                       /* initializer not found  */
1056                 if (verbose) {
1057                         char logtext[MAXLOGTEXT];
1058                         sprintf(logtext, "Warning: class has no instance-initializer: ");
1059                         utf_sprint_classname(logtext + strlen(logtext), c->name);
1060                         log_text(logtext);
1061                 }
1062                 return o;
1063         }
1064
1065         /* call initializer */
1066
1067 #if defined(__I386__) || defined(__POWERPC__)
1068         asm_calljavafunction(m, o, (void *) i, NULL, NULL);
1069 #else
1070         asm_calljavafunction(m, o, (void *) (s8) i, NULL, NULL);
1071 #endif
1072
1073         return o;
1074 }
1075
1076
1077 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
1078 {
1079         methodinfo *m;
1080         java_objectheader *o;
1081
1082         if (!c)
1083                 return *exceptionptr;
1084
1085         o = builtin_new(c);          /* create object          */
1086         
1087         if (!o) return NULL;
1088
1089         /* find initializer */
1090
1091         m = class_findmethod(c,
1092                                                  utf_new_char("<init>"),
1093                                                  utf_new_char("(Ljava/lang/Throwable;)V"));
1094                                                       
1095         if (!m) {                                       /* initializer not found  */
1096                 if (verbose) {
1097                         char logtext[MAXLOGTEXT];
1098                         sprintf(logtext, "Warning: class has no instance-initializer: ");
1099                         utf_sprint_classname(logtext + strlen(logtext), c->name);
1100                         log_text(logtext);
1101                 }
1102                 return o;
1103         }
1104
1105         /* call initializer */
1106
1107         asm_calljavafunction(m, o, t, NULL, NULL);
1108
1109         return o;
1110 }
1111
1112
1113 /******************** function: stringtable_update ****************************
1114
1115         traverses the javastring hashtable and sets the vftbl-entries of
1116         javastrings which were temporarily set to NULL, because 
1117         java.lang.Object was not yet loaded
1118
1119 *******************************************************************************/
1120  
1121 void stringtable_update ()
1122 {
1123         java_lang_String *js;   
1124         java_chararray *a;
1125         literalstring *s;       /* hashtable entry */
1126         int i;
1127
1128         for (i = 0; i < string_hash.size; i++) {
1129                 s = string_hash.ptr[i];
1130                 if (s) {
1131                         while (s) {
1132                                                                 
1133                                 js = (java_lang_String *) s->string;
1134                                 
1135                                 if (!js || !js->value) 
1136                                         /* error in hashtable found */
1137                                         panic("invalid literalstring in hashtable");
1138
1139                                 a = js->value;
1140
1141                                 if (!js->header.vftbl) 
1142                                         /* vftbl of javastring is NULL */ 
1143                                         js->header.vftbl = class_java_lang_String->vftbl;
1144
1145                                 if (!a->header.objheader.vftbl) 
1146                                         /* vftbl of character-array is NULL */ 
1147                                         a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
1148
1149                                 /* follow link in external hash chain */
1150                                 s = s->hashlink;
1151                         }       
1152                 }               
1153         }
1154 }
1155
1156
1157 /************************* function: u2_utflength ***************************
1158
1159         returns the utf length in bytes of a u2 array 
1160
1161 *****************************************************************************/
1162
1163 u4 u2_utflength(u2 *text, u4 u2_length)
1164 {
1165         u4 result_len =  0;  /* utf length in bytes  */
1166         u2 ch;               /* current unicode character */
1167         u4 len;
1168         
1169         for (len = 0; len < u2_length; len++) {
1170                 /* next unicode character */
1171                 ch = *text++;
1172           
1173                 /* determine bytes required to store unicode character as utf */
1174                 if (ch && (ch < 0x80)) 
1175                         result_len++;
1176                 else if (ch < 0x800)
1177                         result_len += 2;        
1178                 else 
1179                         result_len += 3;        
1180         }
1181
1182     return result_len;
1183 }
1184
1185
1186 /********************* function: utf_new_u2 ***********************************
1187
1188         make utf symbol from u2 array, 
1189         if isclassname is true '.' is replaced by '/'
1190
1191 *******************************************************************************/
1192
1193 utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
1194 {
1195         char *buffer; /* memory buffer for  unicode characters */
1196         char *pos;    /* pointer to current position in buffer */
1197         u4 left;      /* unicode characters left */
1198         u4 buflength; /* utf length in bytes of the u2 array  */
1199         utf *result;  /* resulting utf-string */
1200         int i;          
1201
1202         /* determine utf length in bytes and allocate memory */
1203         /* printf("utf_new_u2: unicode_length=%d\n",unicode_length);            */
1204         buflength = u2_utflength(unicode_pos, unicode_length); 
1205         buffer    = MNEW(char, buflength);
1206  
1207         /* memory allocation failed */
1208         if (!buffer) {
1209                 printf("length: %d\n",buflength);
1210                 log_text("utf_new_u2:buffer==NULL");
1211         }
1212
1213         left = buflength;
1214         pos  = buffer;
1215
1216         for (i = 0; i++ < unicode_length; unicode_pos++) {
1217                 /* next unicode character */
1218                 u2 c = *unicode_pos;
1219                 
1220                 if ((c != 0) && (c < 0x80)) {
1221                         /* 1 character */       
1222                         left--;
1223                 if ((int) left < 0) break;
1224                         /* convert classname */
1225                         if (isclassname && c == '.')
1226                                 *pos++ = '/';
1227                         else
1228                                 *pos++ = (char) c;
1229
1230                 } else if (c < 0x800) {             
1231                         /* 2 characters */                              
1232                 unsigned char high = c >> 6;
1233                 unsigned char low  = c & 0x3F;
1234                         left = left - 2;
1235                 if ((int) left < 0) break;
1236                 *pos++ = high | 0xC0; 
1237                 *pos++ = low  | 0x80;     
1238
1239                 } else {         
1240                 /* 3 characters */                              
1241                 char low  = c & 0x3f;
1242                 char mid  = (c >> 6) & 0x3F;
1243                 char high = c >> 12;
1244                         left = left - 3;
1245                 if ((int) left < 0) break;
1246                 *pos++ = high | 0xE0; 
1247                 *pos++ = mid  | 0x80;  
1248                 *pos++ = low  | 0x80;   
1249                 }
1250         }
1251         
1252         /* insert utf-string into symbol-table */
1253         result = utf_new(buffer,buflength);
1254
1255         MFREE(buffer, char, buflength);
1256
1257         return result;
1258 }
1259
1260
1261 /********************* function: javastring_toutf *****************************
1262
1263         make utf symbol from javastring
1264
1265 *******************************************************************************/
1266
1267 utf *javastring_toutf(java_lang_String *string, bool isclassname)
1268 {
1269         java_lang_String *str = (java_lang_String *) string;
1270
1271 /*      printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */
1272 /*      fflush(stdout); */
1273
1274         return utf_new_u2(str->value->data + str->offset, str->count, isclassname);
1275 }
1276
1277
1278 /********************* function: literalstring_u2 *****************************
1279
1280     searches for the javastring with the specified u2-array in 
1281     the string hashtable, if there is no such string a new one is 
1282     created 
1283
1284     if copymode is true a copy of the u2-array is made
1285
1286 *******************************************************************************/
1287
1288 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
1289                                                                         bool copymode)
1290 {
1291     literalstring *s;                /* hashtable element */
1292     java_lang_String *js;            /* u2-array wrapped in javastring */
1293     java_chararray *stringdata;      /* copy of u2-array */      
1294     u4 key;   
1295     u4 slot;  
1296     u2 i;
1297
1298 //#define DEBUG_LITERALSTRING_U2
1299 #ifdef DEBUG_LITERALSTRING_U2
1300     printf("literalstring_u2: length=%d, offset=%d\n", length, offset);
1301         fflush(stdout);
1302 #endif
1303     
1304     /* find location in hashtable */
1305     key  = unicode_hashkey(a->data + offset, length);
1306     slot = key & (string_hash.size - 1);
1307     s    = string_hash.ptr[slot];
1308
1309     while (s) {
1310                 js = (java_lang_String *) s->string;
1311
1312                 if (length == js->count) {
1313                         /* compare text */
1314                         for (i = 0; i < length; i++) {
1315                                 if (a->data[offset + i] != js->value->data[i])
1316                                         goto nomatch;
1317                         }
1318
1319                         /* string already in hashtable, free memory */
1320                         if (!copymode)
1321                                 lit_mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
1322
1323 #ifdef DEBUG_LITERALSTRING_U2
1324                         printf("literalstring_u2: foundentry at %p\n", js);
1325                         utf_display(javastring_toutf(js, 0));
1326                         printf("\n\n");
1327                         fflush(stdout);
1328 #endif
1329                         return (java_objectheader *) js;
1330                 }
1331
1332         nomatch:
1333                 /* follow link in external hash chain */
1334                 s = s->hashlink;
1335     }
1336
1337     if (copymode) {
1338                 /* create copy of u2-array for new javastring */
1339                 u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
1340                 stringdata = lit_mem_alloc(arraysize);
1341 /*              memcpy(stringdata, a, arraysize); */
1342                 memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader));
1343                 memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
1344
1345     } else {
1346                 stringdata = a;
1347         }
1348
1349     /* location in hashtable found, complete arrayheader */
1350     stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
1351     stringdata->header.size = length;
1352
1353     /* create new javastring */
1354     js = LNEW(java_lang_String);
1355         /* TWISTI */
1356 /*      js->header.vftbl = class_java_lang_String->vftbl; */
1357     js->header.vftbl = class_load(class_new(utf_new_char("java/lang/String")))->vftbl;
1358     js->value  = stringdata;
1359     js->offset = 0;
1360     js->count  = length;
1361
1362     /* create new literalstring */
1363     s = NEW(literalstring);
1364     s->hashlink = string_hash.ptr[slot];
1365     s->string   = (java_objectheader *) js;
1366     string_hash.ptr[slot] = s;
1367
1368     /* update numbe of hashtable entries */
1369     string_hash.entries++;
1370
1371     /* reorganization of hashtable */       
1372     if (string_hash.entries > (string_hash.size * 2)) {
1373                 /* reorganization of hashtable, average length of 
1374          the external chains is approx. 2                */  
1375
1376                 u4 i;
1377                 literalstring *s;     
1378                 hashtable newhash; /* the new hashtable */
1379       
1380                 /* create new hashtable, double the size */
1381                 init_hashtable(&newhash, string_hash.size * 2);
1382                 newhash.entries = string_hash.entries;
1383       
1384                 /* transfer elements to new hashtable */
1385                 for (i = 0; i < string_hash.size; i++) {
1386                         s = string_hash.ptr[i];
1387                         while (s) {
1388                                 literalstring *nexts = s->hashlink;
1389                                 js   = (java_lang_String *) s->string;
1390                                 slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1);
1391           
1392                                 s->hashlink = newhash.ptr[slot];
1393                                 newhash.ptr[slot] = s;
1394         
1395                                 /* follow link in external hash chain */  
1396                                 s = nexts;
1397                         }
1398                 }
1399         
1400                 /* dispose old table */ 
1401                 MFREE(string_hash.ptr, void*, string_hash.size);
1402                 string_hash = newhash;
1403     }
1404
1405 #ifdef DEBUG_LITERALSTRING_U2
1406         printf("literalstring_u2: newly created at %p\n", js);
1407         utf_display(javastring_toutf(js, 0));
1408         printf("\n\n");
1409         fflush(stdout);
1410 #endif
1411                         
1412     return (java_objectheader *) js;
1413 }
1414
1415
1416 /******************** Function: literalstring_new *****************************
1417
1418     creates a new javastring with the text of the utf-symbol
1419     and inserts it into the string hashtable
1420
1421 *******************************************************************************/
1422
1423 java_objectheader *literalstring_new(utf *u)
1424 {
1425     char *utf_ptr = u->text;         /* pointer to current unicode character in utf string */
1426     u4 utflength  = utf_strlen(u);   /* length of utf-string if uncompressed */
1427     java_chararray *a;               /* u2-array constructed from utf string */
1428     u4 i;
1429
1430     /* allocate memory */ 
1431     a = lit_mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
1432
1433     /* convert utf-string to u2-array */
1434     for (i = 0; i < utflength; i++)
1435                 a->data[i] = utf_nextu2(&utf_ptr);
1436
1437     return literalstring_u2(a, utflength, 0, false);
1438 }
1439
1440
1441 /********************** function: literalstring_free **************************
1442
1443         removes a javastring from memory                       
1444
1445 ******************************************************************************/
1446
1447 void literalstring_free(java_objectheader* sobj)
1448 {
1449         java_lang_String *s = (java_lang_String *) sobj;
1450         java_chararray *a = s->value;
1451
1452         /* dispose memory of java.lang.String object */
1453         LFREE(s, java_lang_String);
1454
1455         /* dispose memory of java-characterarray */
1456         LFREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
1457 }
1458
1459
1460 void copy_vftbl(vftbl **dest, vftbl *src)
1461 {
1462     *dest = src;
1463 #if 0
1464     /* XXX this kind of copying does not work (in the general
1465      * case). The interface tables would have to be copied, too. I
1466      * don't see why we should make a copy anyway. -Edwin
1467      */
1468         *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
1469         memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
1470         memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
1471 #endif
1472 }
1473
1474
1475 /******************************************************************************************                                                                                                             
1476
1477         creates method signature (excluding return type) from array of 
1478         class-objects representing the parameters of the method 
1479
1480 *******************************************************************************************/
1481
1482
1483 utf *create_methodsig(java_objectarray* types, char *retType)
1484 {
1485     char *buffer;       /* buffer for building the desciptor */
1486     char *pos;          /* current position in buffer */
1487     utf *result;        /* the method signature */
1488     u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
1489     u4 i, j;
1490  
1491     if (!types) return NULL;
1492
1493     /* determine required buffer-size */    
1494     for (i = 0; i < types->header.size; i++) {
1495                 classinfo *c = (classinfo *) types->data[i];
1496                 buffer_size  = buffer_size + c->name->blength + 2;
1497     }
1498
1499     if (retType) buffer_size += strlen(retType);
1500
1501     /* allocate buffer */
1502     buffer = MNEW(u1, buffer_size);
1503     pos    = buffer;
1504     
1505     /* method-desciptor starts with parenthesis */
1506     *pos++ = '(';
1507
1508     for (i = 0; i < types->header.size; i++) {
1509                 char ch;           
1510
1511                 /* current argument */
1512             classinfo *c = (classinfo *) types->data[i];
1513
1514             /* current position in utf-text */
1515             char *utf_ptr = c->name->text; 
1516             
1517             /* determine type of argument */
1518             if ((ch = utf_nextu2(&utf_ptr)) == '[') {
1519                 /* arrayclass */
1520                 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1521                                 *pos++ = *utf_ptr; /* copy text */
1522                         }
1523
1524             } else {            
1525                         /* check for primitive types */
1526                         for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
1527                                 char *utf_pos   = utf_ptr - 1;
1528                                 char *primitive = primitivetype_table[j].wrapname;
1529
1530                                 /* compare text */
1531                                 while (utf_pos < utf_end(c->name)) {
1532                                         if (*utf_pos++ != *primitive++) goto nomatch;
1533                                 }
1534
1535                                 /* primitive type found */
1536                                 *pos++ = primitivetype_table[j].typesig;
1537                                 goto next_type;
1538
1539                         nomatch:
1540                                 ;
1541                         }
1542
1543                         /* no primitive type and no arrayclass, so must be object */
1544                         *pos++ = 'L';
1545
1546                         /* copy text */
1547                         for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
1548                                 *pos++ = *utf_ptr;
1549                         }
1550
1551                         *pos++ = ';';
1552
1553                 next_type:
1554                         ;
1555                 }  
1556     }       
1557
1558     *pos++ = ')';
1559
1560     if (retType) {
1561                 for (i = 0; i < strlen(retType); i++) {
1562                         *pos++ = retType[i];
1563                 }
1564     }
1565
1566     /* create utf-string */
1567     result = utf_new(buffer, (pos - buffer));
1568     MFREE(buffer, u1, buffer_size);
1569
1570     return result;
1571 }
1572
1573
1574 /******************************************************************************************
1575
1576         retrieve the next argument or returntype from a descriptor
1577         and return the corresponding class 
1578
1579 *******************************************************************************************/
1580
1581 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
1582 {
1583     classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
1584                                          (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
1585     if (!c)
1586         /* unknown type */
1587         panic("illegal descriptor");
1588
1589     if (skip) return NULL;
1590
1591     use_class_as_object(c);
1592     return c;
1593 }
1594
1595
1596 /******************************************************************************************
1597
1598         use the descriptor of a method to generate a java/lang/Class array
1599         which contains the classes of the parametertypes of the method
1600
1601 *******************************************************************************************/
1602
1603 java_objectarray* get_parametertypes(methodinfo *m) 
1604 {
1605     utf  *descr    =  m->descriptor;    /* method-descriptor */ 
1606     char *utf_ptr  =  descr->text;      /* current position in utf-text */
1607     char *desc_end =  utf_end(descr);   /* points behind utf string     */
1608     java_objectarray* result;
1609     int parametercount = 0;
1610     int i;
1611
1612     /* skip '(' */
1613     utf_nextu2(&utf_ptr);
1614   
1615     /* determine number of parameters */
1616     while ( *utf_ptr != ')' ) {
1617         get_type(&utf_ptr,desc_end,true);
1618         parametercount++;
1619     }
1620
1621     /* create class-array */
1622     result = builtin_anewarray(parametercount, class_java_lang_Class);
1623
1624     utf_ptr  =  descr->text;
1625     utf_nextu2(&utf_ptr);
1626
1627     /* get returntype classes */
1628     for (i = 0; i < parametercount; i++)
1629             result->data[i] = (java_objectheader *) get_type(&utf_ptr,desc_end, false);
1630
1631     return result;
1632 }
1633
1634
1635
1636
1637
1638 /******************************************************************************************
1639
1640         get the exceptions which can be thrown by a method      
1641
1642 *******************************************************************************************/
1643
1644 java_objectarray* get_exceptiontypes(methodinfo *m) {
1645     u2 exccount=m->thrownexceptionscount;
1646     u2 i;
1647     java_objectarray *result;
1648     /* create class-array */
1649     result = builtin_anewarray(exccount, class_java_lang_Class);
1650     for (i=0;i<exccount;i++) {
1651         java_objectheader *oh=(java_objectheader*)(m->thrownexceptions[i]);
1652         use_class_as_object(oh);
1653         result->data[i]=oh;
1654     }
1655     return result;
1656 }
1657
1658
1659
1660
1661
1662 /******************************************************************************************
1663
1664         get the returntype class of a method
1665
1666 *******************************************************************************************/
1667
1668 classinfo *get_returntype(methodinfo *m) 
1669 {
1670         char *utf_ptr;   /* current position in utf-text */
1671         char *desc_end;  /* points behind utf string     */
1672         utf *desc = m->descriptor; /* method-descriptor  */
1673
1674         utf_ptr  = desc->text;
1675         desc_end = utf_end(desc);
1676
1677         /* ignore parametertypes */
1678         while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
1679                 /* skip */ ;
1680
1681         return get_type(&utf_ptr,desc_end, false);
1682 }
1683
1684
1685 /*****************************************************************************/
1686 /*****************************************************************************/
1687
1688
1689 /*--------------------------------------------------------*/
1690 void printNativeCall(nativeCall nc) {
1691   int i,j;
1692
1693   printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
1694   for (i=0; i<nc.methCnt; i++) {  
1695       printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
1696
1697     for (j=0; j<nc.callCnt[i]; j++) {  
1698         printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
1699         nc.methods[i].methodCalls[j].classname, 
1700         nc.methods[i].methodCalls[j].methodname, 
1701         nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1702       }
1703     }
1704   printf("-+++++--------------------\n");fflush(stdout);
1705 }
1706
1707 /*--------------------------------------------------------*/
1708 void printCompNativeCall(nativeCompCall nc) {
1709   int i,j;
1710   printf("printCompNativeCall BEGIN\n");fflush(stdout); 
1711   printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
1712   utf_display(nc.classname); fflush(stdout);
1713   
1714   for (i=0; i<nc.methCnt; i++) {  
1715     printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
1716     utf_display(nc.methods[i].methodname); fflush(stdout);
1717     utf_display(nc.methods[i].descriptor);fflush(stdout);
1718     printf("\n");fflush(stdout);
1719
1720     for (j=0; j<nc.callCnt[i]; j++) {  
1721       printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
1722         utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
1723         utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
1724         utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
1725         printf("\n");fflush(stdout);
1726       }
1727     }
1728 printf("---------------------\n");fflush(stdout);
1729 }
1730
1731
1732 /*--------------------------------------------------------*/
1733 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d ) 
1734 {
1735     int i = 0;
1736     int j = 0;
1737     int cnt = 0;
1738     classMeth mc;
1739     mc.i_class = i;
1740     mc.j_method = j;
1741     mc.methCnt = cnt;
1742
1743     return mc;
1744 }
1745
1746 /*--------------------------------------------------------*/
1747 nativeCall* findNativeClassCalls(char *aclassname ) {
1748 int i;
1749
1750 for (i=0;i<NATIVECALLSSIZE; i++) {
1751    /* convert table to utf later to speed up search */ 
1752    if (strcmp(nativeCalls[i].classname, aclassname) == 0) 
1753         return &nativeCalls[i];
1754    }
1755
1756 return NULL;
1757 }
1758 /*--------------------------------------------------------*/
1759 /*--------------------------------------------------------*/
1760 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
1761   int i,j;
1762
1763
1764   ncc->classname = utf_new_char(nc.classname); 
1765   ncc->methCnt = nc.methCnt;
1766   
1767   for (i=0; i<nc.methCnt; i++) {  
1768     ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
1769     ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
1770     ncc->callCnt[i] = nc.callCnt[i];
1771
1772     for (j=0; j<nc.callCnt[i]; j++) {  
1773
1774         ncc->methods[i].methodCalls[j].classname  = utf_new_char(nc.methods[i].methodCalls[j].classname);
1775
1776         if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
1777           ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
1778           ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
1779           }
1780         else {
1781           ncc->methods[i].methodCalls[j].methodname = NULL;
1782           ncc->methods[i].methodCalls[j].descriptor = NULL;
1783           }
1784       }
1785     }
1786 }
1787
1788
1789
1790 /*--------------------------------------------------------*/
1791
1792 bool natcall2utf(bool natcallcompdone) {
1793 int i;
1794
1795 if (natcallcompdone) 
1796         return true;
1797
1798 for (i=0;i<NATIVECALLSSIZE; i++) {
1799    utfNativeCall  (nativeCalls[i], &nativeCompCalls[i]);  
1800    }
1801
1802 return true;
1803 }
1804
1805 /*--------------------------------------------------------*/
1806
1807
1808 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end,classinfo **start)
1809 {
1810 #if defined(__GNUC__)
1811 #warning platform dependend
1812 #endif
1813         java_objectarray *tmpArray;
1814         int i;
1815         classinfo **current;
1816         classinfo *c;
1817         size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1818 /*      printf("end %p, start %p, size %ld\n",end,start,size);*/
1819         if (!class_java_lang_Class)
1820                 class_java_lang_Class = class_new(utf_new_char ("java/lang/Class"));
1821         if (!class_java_lang_SecurityManager)
1822                 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1823         if (size>0) {
1824                 if (start==class_java_lang_SecurityManager) {
1825                         size--;
1826                         start--;
1827                 }
1828         }
1829         tmpArray=builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
1830
1831         for(i=0,current=start;i<size;i++,current--) {
1832                 c=*current;
1833 /*              printf("%d\n",i);
1834                 utf_display(c->name);*/
1835                 use_class_as_object(c);
1836                 tmpArray->data[i]=c;
1837         }
1838         return tmpArray;
1839
1840 }
1841
1842 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end,classinfo **start)
1843 {
1844 #if defined(__GNUC__)
1845 #warning platform dependend
1846 #endif
1847         int i;
1848         classinfo **current;
1849         classinfo *c;
1850         classinfo *privilegedAction;
1851         size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*);
1852 /*      log_text("builtin_asm_getclassloader");
1853         printf("end %p, start %p, size %ld\n",end,start,size);*/
1854
1855         if (!class_java_lang_SecurityManager)
1856                 class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager"));
1857         if (size>0) {
1858                 if (start==class_java_lang_SecurityManager) {
1859                         size--;
1860                         start--;
1861                 }
1862         }
1863
1864         privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
1865
1866         for(i=0,current=start;i<size;i++,current--) {
1867                 c=*current;
1868                 if (c==privilegedAction) return NULL;
1869                 if (c->classloader) return c->classloader;
1870         }
1871         return NULL;
1872
1873
1874
1875
1876 /*
1877         log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
1878         init_systemclassloader();
1879
1880         return SystemClassLoader;*/
1881 }
1882
1883 /*
1884  * These are local overrides for various environment variables in Emacs.
1885  * Please do not remove this and leave it at the end of the file, where
1886  * Emacs will automagically detect them.
1887  * ---------------------------------------------------------------------
1888  * Local variables:
1889  * mode: c
1890  * indent-tabs-mode: t
1891  * c-basic-offset: 4
1892  * tab-width: 4
1893  * End:
1894  */