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