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