Removed ProtectionDomain stuff, this is done via gnu classpath.
[cacao.git] / src / native / native.c
1 /* src/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    Changes: Christian Thalinger
32
33    $Id: native.c 2138 2005-03-30 10:23:47Z twisti $
34
35 */
36
37
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <time.h>
41 #include <math.h>
42 #include <string.h>
43 #include <assert.h>
44 #include <sys/time.h>
45 #include <utime.h>
46
47 /* Include files for IO functions */
48
49 #include <fcntl.h>
50 #include <dirent.h>
51 #include <sys/types.h>
52 #ifdef _OSF_SOURCE 
53 #include <sys/mode.h>
54 #endif
55 #include <sys/stat.h>
56
57 #include "config.h"
58 #include "cacao/cacao.h"
59 #include "mm/memory.h"
60 #include "native/jni.h"
61 #include "native/native.h"
62 #include "native/include/java_lang_Throwable.h"
63 #include "toolbox/logging.h"
64 #include "vm/builtin.h"
65 #include "vm/exceptions.h"
66 #include "vm/global.h"
67 #include "vm/loader.h"
68 #include "vm/options.h"
69 #include "vm/stringlocal.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 #include "nativetable.inc"
78
79
80 /************* use classinfo structure as java.lang.Class object **************/
81
82 void use_class_as_object(classinfo *c) 
83 {
84         if (!c->classvftbl) {
85                 /* is the class loaded */
86                 if (!c->loaded)
87 /*                      if (!class_load(c)) */
88 /*                              throw_exception_exit(); */
89                         panic("use_class_as_object: class_load should not happen");
90
91                 /* is the class linked */
92                 if (!c->linked)
93                         if (!class_link(c))
94                                 throw_exception_exit();
95
96                 /*if (class_java_lang_Class ==0) panic("java/lang/Class not loaded in use_class_as_object");
97                 if (class_java_lang_Class->vftbl ==0) panic ("vftbl == 0 in use_class_as_object");*/
98                 c->header.vftbl = class_java_lang_Class->vftbl;
99                 c->classvftbl = true;
100         }
101 }
102
103
104 /************************** tables for methods ********************************/
105
106 #undef JOWENN_DEBUG
107 #undef JOWENN_DEBUG1
108
109 #ifdef STATIC_CLASSPATH
110 #define NATIVETABLESIZE  (sizeof(nativetable)/sizeof(struct nativeref))
111
112 /* table for fast string comparison */
113 static nativecompref nativecomptable[NATIVETABLESIZE];
114
115 /* string comparsion table initialized */
116 static bool nativecompdone = false;
117 #endif
118
119
120 /* XXX don't define this in a header file!!! */
121
122 static struct nativeCall nativeCalls[] =
123 {
124 #include "nativecalls.inc"
125 };
126
127 #define NATIVECALLSSIZE    (sizeof(nativeCalls) / sizeof(struct nativeCall))
128
129 struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE];
130
131
132 /* native_loadclasses **********************************************************
133
134    Load classes required for native methods.
135
136 *******************************************************************************/
137
138 bool native_init(void)
139 {
140         static int classesLoaded = 0; /*temporary hack JoWenn*/
141 #if !defined(STATIC_CLASSPATH)
142         void *p;
143 #endif
144
145         if (classesLoaded)
146                 return true;
147
148         classesLoaded = 1;
149
150 #if !defined(STATIC_CLASSPATH)
151         /* We need to access the dummy native table, not only to remove a warning */
152         /* but to be sure that the table is not optimized away (gcc does this     */
153         /* since 3.4).                                                            */
154         p = &dummynativetable;
155 #endif
156
157         /* load classes for wrapping primitive types */
158
159         if (!class_load(class_java_lang_Void) ||
160                 !class_link(class_java_lang_Void))
161                 return false;
162
163         if (!class_load(class_java_lang_Boolean) ||
164                 !class_link(class_java_lang_Boolean))
165                 return false;
166
167         if (!class_load(class_java_lang_Byte) ||
168                 !class_link(class_java_lang_Byte))
169                 return false;
170
171         if (!class_load(class_java_lang_Character) ||
172                 !class_link(class_java_lang_Character))
173                 return false;
174
175         if (!class_load(class_java_lang_Short) ||
176                 !class_link(class_java_lang_Short))
177                 return false;
178
179         if (!class_load(class_java_lang_Integer) ||
180                 !class_link(class_java_lang_Integer))
181                 return false;
182
183         if (!class_load(class_java_lang_Long) ||
184                 !class_link(class_java_lang_Long))
185                 return false;
186
187         if (!class_load(class_java_lang_Float) ||
188                 !class_link(class_java_lang_Float))
189                 return false;
190
191         if (!class_load(class_java_lang_Double) ||
192                 !class_link(class_java_lang_Double))
193                 return false;
194
195         /* everything's ok */
196
197         return true;
198 }
199
200
201 /*********************** Function: native_findfunction *************************
202
203         Looks up a method (must have the same class name, method name, descriptor
204         and 'static'ness) and returns a function pointer to it.
205         Returns: function pointer or NULL (if there is no such method)
206
207         Remark: For faster operation, the names/descriptors are converted from C
208                 strings to Unicode the first time this function is called.
209
210 *******************************************************************************/
211
212 functionptr native_findfunction(utf *cname, utf *mname, 
213                                                                 utf *desc, bool isstatic)
214 {
215 #ifdef STATIC_CLASSPATH
216         int i;
217         /* entry of table for fast string comparison */
218         struct nativecompref *n;
219         /* for warning message if no function is found */
220         char *buffer;                   
221         int buffer_len;
222
223         isstatic = isstatic ? true : false;
224         
225         if (!nativecompdone) {
226                 for (i = 0; i < NATIVETABLESIZE; i++) {
227                         nativecomptable[i].classname  = 
228                                 utf_new_char(nativetable[i].classname);
229                         nativecomptable[i].methodname = 
230                                 utf_new_char(nativetable[i].methodname);
231                         nativecomptable[i].descriptor = 
232                                 utf_new_char(nativetable[i].descriptor);
233                         nativecomptable[i].isstatic   = 
234                                 nativetable[i].isstatic;
235                         nativecomptable[i].func       = 
236                                 nativetable[i].func;
237                 }
238                 nativecompdone = true;
239         }
240
241 #ifdef JOWENN_DEBUG
242         buffer_len = 
243                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
244         
245         buffer = MNEW(char, buffer_len);
246
247         strcpy(buffer, "searching matching function in native table:");
248         utf_sprint(buffer+strlen(buffer), mname);
249         strcpy(buffer+strlen(buffer), ": ");
250         utf_sprint(buffer+strlen(buffer), desc);
251         strcpy(buffer+strlen(buffer), " for class ");
252         utf_sprint(buffer+strlen(buffer), cname);
253
254         log_text(buffer);       
255
256         MFREE(buffer, char, buffer_len);
257 #endif
258                 
259         for (i = 0; i < NATIVETABLESIZE; i++) {
260                 n = &(nativecomptable[i]);
261
262                 if (cname == n->classname && mname == n->methodname &&
263                     desc == n->descriptor && isstatic == n->isstatic)
264                         return n->func;
265 #ifdef JOWENN_DEBUG
266                         else {
267                                 if (cname == n->classname && mname == n->methodname )  log_text("static and descriptor mismatch");
268                         
269                                 else {
270                                         buffer_len = 
271                                           utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
272         
273                                         buffer = MNEW(char, buffer_len);
274
275                                         strcpy(buffer, "comparing with:");
276                                         utf_sprint(buffer+strlen(buffer), n->methodname);
277                                         strcpy (buffer+strlen(buffer), ": ");
278                                         utf_sprint(buffer+strlen(buffer), n->descriptor);
279                                         strcpy(buffer+strlen(buffer), " for class ");
280                                         utf_sprint(buffer+strlen(buffer), n->classname);
281
282                                         log_text(buffer);       
283
284                                         MFREE(buffer, char, buffer_len);
285                                 }
286                         } 
287 #endif
288         }
289
290                 
291         /* no function was found, display warning */
292
293         buffer_len = 
294                 utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
295
296         buffer = MNEW(char, buffer_len);
297
298         strcpy(buffer, "warning: native function ");
299         utf_sprint(buffer + strlen(buffer), mname);
300         strcpy(buffer + strlen(buffer), ": ");
301         utf_sprint(buffer + strlen(buffer), desc);
302         strcpy(buffer + strlen(buffer), " not found in class ");
303         utf_sprint(buffer + strlen(buffer), cname);
304
305         log_text(buffer);       
306
307         MFREE(buffer, char, buffer_len);
308
309 /*      exit(1); */
310
311         /* keep compiler happy */
312         return NULL;
313 #else
314 /* dynamic classpath */
315   return 0;
316 #endif
317 }
318
319
320 /****************** function class_findfield_approx ****************************
321         
322         searches in 'classinfo'-structure for a field with the
323         specified name
324
325 *******************************************************************************/
326  
327 fieldinfo *class_findfield_approx(classinfo *c, utf *name)
328 {
329         s4 i;
330
331         for (i = 0; i < c->fieldscount; i++) {
332                 /* compare field names */
333                 if ((c->fields[i].name == name))
334                         return &(c->fields[i]);
335         }
336
337         /* field was not found, raise exception */      
338         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
339
340         return NULL;
341 }
342
343
344 s4 class_findfield_index_approx(classinfo *c, utf *name)
345 {
346         s4 i;
347
348         for (i = 0; i < c->fieldscount; i++) {
349                 /* compare field names */
350                 if ((c->fields[i].name == name))
351                         return i;
352         }
353
354         /* field was not found, raise exception */      
355         *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
356
357         return -1;
358 }
359
360
361 /* native_new_and_init *********************************************************
362
363    Creates a new object on the heap and calls the initializer.
364    Returns the object pointer or NULL if memory is exhausted.
365                         
366 *******************************************************************************/
367
368 java_objectheader *native_new_and_init(classinfo *c)
369 {
370         methodinfo *m;
371         java_objectheader *o;
372
373         if (!c)
374                 return *exceptionptr;
375
376         /* create object */
377
378         o = builtin_new(c);
379         
380         if (!o)
381                 return NULL;
382
383         /* find initializer */
384
385         m = class_findmethod(c, utf_init, utf_void__void);
386                                                       
387         /* initializer not found */
388
389         if (!m)
390                 return o;
391
392         /* call initializer */
393
394         asm_calljavafunction(m, o, NULL, NULL, NULL);
395
396         return o;
397 }
398
399
400 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
401 {
402         methodinfo *m;
403         java_objectheader *o;
404
405         if (!c)
406                 return *exceptionptr;
407
408         /* create object */
409
410         o = builtin_new(c);
411
412         if (!o)
413                 return NULL;
414
415         /* find initializer */
416
417         m = class_resolveclassmethod(c,
418                                                                  utf_init,
419                                                                  utf_java_lang_String__void,
420                                                                  NULL,
421                                                                  true);
422
423         /* initializer not found */
424
425         if (!m)
426                 return NULL;
427
428         /* call initializer */
429
430         asm_calljavafunction(m, o, s, NULL, NULL);
431
432         return o;
433 }
434
435
436 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
437 {
438         methodinfo *m;
439         java_objectheader *o;
440
441         if (!c)
442                 return *exceptionptr;
443
444         /* create object */
445
446         o = builtin_new(c);
447         
448         if (!o)
449                 return NULL;
450
451         /* find initializer */
452
453         m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true);
454
455         /* initializer not found  */
456
457         if (!m)
458                 return NULL;
459
460         /* call initializer */
461
462         asm_calljavafunction(m, o, (void *) (ptrint) i, NULL, NULL);
463
464         return o;
465 }
466
467
468 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
469 {
470         methodinfo *m;
471         java_objectheader *o;
472
473         if (!c)
474                 return *exceptionptr;
475
476         /* create object */
477
478         o = builtin_new(c);
479         
480         if (!o)
481                 return NULL;
482
483         /* find initializer */
484
485         m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void);
486                                                       
487         /* initializer not found */
488
489         if (!m)
490                 return NULL;
491
492         /* call initializer */
493
494         asm_calljavafunction(m, o, t, NULL, NULL);
495
496         return o;
497 }
498
499
500 void copy_vftbl(vftbl_t **dest, vftbl_t *src)
501 {
502     *dest = src;
503 #if 0
504     /* XXX this kind of copying does not work (in the general
505      * case). The interface tables would have to be copied, too. I
506      * don't see why we should make a copy anyway. -Edwin
507      */
508         *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
509         memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
510         memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
511 #endif
512 }
513
514
515 /******************************************************************************************                                                                                                             
516
517         creates method signature (excluding return type) from array of 
518         class-objects representing the parameters of the method 
519
520 *******************************************************************************************/
521
522
523 utf *create_methodsig(java_objectarray* types, char *retType)
524 {
525     char *buffer;       /* buffer for building the desciptor */
526     char *pos;          /* current position in buffer */
527     utf *result;        /* the method signature */
528     u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */
529     u4 i, j;
530  
531     if (!types) return NULL;
532
533     /* determine required buffer-size */    
534     for (i = 0; i < types->header.size; i++) {
535                 classinfo *c = (classinfo *) types->data[i];
536                 buffer_size  = buffer_size + c->name->blength + 2;
537     }
538
539     if (retType) buffer_size += strlen(retType);
540
541     /* allocate buffer */
542     buffer = MNEW(char, buffer_size);
543     pos    = buffer;
544     
545     /* method-desciptor starts with parenthesis */
546     *pos++ = '(';
547
548     for (i = 0; i < types->header.size; i++) {
549                 char ch;           
550
551                 /* current argument */
552             classinfo *c = (classinfo *) types->data[i];
553
554             /* current position in utf-text */
555             char *utf_ptr = c->name->text; 
556             
557             /* determine type of argument */
558             if ((ch = utf_nextu2(&utf_ptr)) == '[') {
559                 /* arrayclass */
560                 for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
561                                 *pos++ = *utf_ptr; /* copy text */
562                         }
563
564             } else {            
565                         /* check for primitive types */
566                         for (j = 0; j < PRIMITIVETYPE_COUNT; j++) {
567                                 char *utf_pos   = utf_ptr - 1;
568                                 char *primitive = primitivetype_table[j].wrapname;
569
570                                 /* compare text */
571                                 while (utf_pos < utf_end(c->name)) {
572                                         if (*utf_pos++ != *primitive++) goto nomatch;
573                                 }
574
575                                 /* primitive type found */
576                                 *pos++ = primitivetype_table[j].typesig;
577                                 goto next_type;
578
579                         nomatch:
580                                 ;
581                         }
582
583                         /* no primitive type and no arrayclass, so must be object */
584                         *pos++ = 'L';
585
586                         /* copy text */
587                         for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) {
588                                 *pos++ = *utf_ptr;
589                         }
590
591                         *pos++ = ';';
592
593                 next_type:
594                         ;
595                 }  
596     }       
597
598     *pos++ = ')';
599
600     if (retType) {
601                 for (i = 0; i < strlen(retType); i++) {
602                         *pos++ = retType[i];
603                 }
604     }
605
606     /* create utf-string */
607     result = utf_new(buffer, (pos - buffer));
608     MFREE(buffer, char, buffer_size);
609
610     return result;
611 }
612
613
614 /******************************************************************************************
615
616         retrieve the next argument or returntype from a descriptor
617         and return the corresponding class 
618
619 *******************************************************************************************/
620
621 classinfo *get_type(char **utf_ptr,char *desc_end, bool skip)
622 {
623     classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr,
624                                          (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD);
625     if (!c)
626         /* unknown type */
627         panic("illegal descriptor");
628
629     if (skip) return NULL;
630
631     use_class_as_object(c);
632     return c;
633 }
634
635
636 /* get_parametertypes **********************************************************
637
638    use the descriptor of a method to generate a java/lang/Class array
639    which contains the classes of the parametertypes of the method
640
641 *******************************************************************************/
642
643 java_objectarray* get_parametertypes(methodinfo *m) 
644 {
645     utf  *descr    =  m->descriptor;    /* method-descriptor */ 
646     char *utf_ptr  =  descr->text;      /* current position in utf-text */
647     char *desc_end =  utf_end(descr);   /* points behind utf string     */
648     java_objectarray* result;
649     int parametercount = 0;
650     int i;
651
652     /* skip '(' */
653     utf_nextu2(&utf_ptr);
654   
655     /* determine number of parameters */
656     while (*utf_ptr != ')') {
657         get_type(&utf_ptr, desc_end, true);
658                 parametercount++;
659     }
660
661     /* create class-array */
662     result = builtin_anewarray(parametercount, class_java_lang_Class);
663
664     utf_ptr = descr->text;
665     utf_nextu2(&utf_ptr);
666
667     /* get returntype classes */
668     for (i = 0; i < parametercount; i++)
669             result->data[i] =
670                         (java_objectheader *) get_type(&utf_ptr, desc_end, false);
671
672     return result;
673 }
674
675
676 /* get_exceptiontypes **********************************************************
677
678    get the exceptions which can be thrown by a method
679
680 *******************************************************************************/
681
682 java_objectarray* get_exceptiontypes(methodinfo *m)
683 {
684     u2 excount;
685     u2 i;
686     java_objectarray *result;
687
688         excount = m->thrownexceptionscount;
689
690     /* create class-array */
691     result = builtin_anewarray(excount, class_java_lang_Class);
692
693     for (i = 0; i < excount; i++) {
694                 java_objectheader *o = (java_objectheader *) (m->thrownexceptions[i]);
695                 use_class_as_object((classinfo *) o);
696                 result->data[i] = o;
697     }
698
699     return result;
700 }
701
702
703
704
705
706 /******************************************************************************************
707
708         get the returntype class of a method
709
710 *******************************************************************************************/
711
712 classinfo *get_returntype(methodinfo *m) 
713 {
714         char *utf_ptr;   /* current position in utf-text */
715         char *desc_end;  /* points behind utf string     */
716         utf *desc = m->descriptor; /* method-descriptor  */
717
718         utf_ptr  = desc->text;
719         desc_end = utf_end(desc);
720
721         /* ignore parametertypes */
722         while ((utf_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
723                 /* skip */ ;
724
725         return get_type(&utf_ptr,desc_end, false);
726 }
727
728
729 /*****************************************************************************/
730 /*****************************************************************************/
731
732
733 /*--------------------------------------------------------*/
734 void printNativeCall(nativeCall nc) {
735   int i,j;
736
737   printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
738   for (i=0; i<nc.methCnt; i++) {  
739       printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
740
741     for (j=0; j<nc.callCnt[i]; j++) {  
742         printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
743         nc.methods[i].methodCalls[j].classname, 
744         nc.methods[i].methodCalls[j].methodname, 
745         nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
746       }
747     }
748   printf("-+++++--------------------\n");fflush(stdout);
749 }
750
751 /*--------------------------------------------------------*/
752 void printCompNativeCall(nativeCompCall nc) {
753   int i,j;
754   printf("printCompNativeCall BEGIN\n");fflush(stdout); 
755   printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
756   utf_display(nc.classname); fflush(stdout);
757   
758   for (i=0; i<nc.methCnt; i++) {  
759     printf("\tMethod=%s %s\n",nc.methods[i].methodname->text,nc.methods[i].descriptor->text);fflush(stdout);
760     utf_display(nc.methods[i].methodname); fflush(stdout);
761     utf_display(nc.methods[i].descriptor);fflush(stdout);
762     printf("\n");fflush(stdout);
763
764     for (j=0; j<nc.callCnt[i]; j++) {  
765       printf("\t\t<%i,%i>bCalled = ",i,j);fflush(stdout);
766         utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout);
767         utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout);
768         utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
769         printf("\n");fflush(stdout);
770       }
771     }
772 printf("---------------------\n");fflush(stdout);
773 }
774
775
776 /*--------------------------------------------------------*/
777 classMeth findNativeMethodCalls(utf *c, utf *m, utf *d ) 
778 {
779     int i = 0;
780     int j = 0;
781     int cnt = 0;
782     classMeth mc;
783     mc.i_class = i;
784     mc.j_method = j;
785     mc.methCnt = cnt;
786
787     return mc;
788 }
789
790 /*--------------------------------------------------------*/
791 nativeCall* findNativeClassCalls(char *aclassname ) {
792 int i;
793
794 for (i=0;i<NATIVECALLSSIZE; i++) {
795    /* convert table to utf later to speed up search */ 
796    if (strcmp(nativeCalls[i].classname, aclassname) == 0) 
797         return &nativeCalls[i];
798    }
799
800 return NULL;
801 }
802 /*--------------------------------------------------------*/
803 /*--------------------------------------------------------*/
804 void utfNativeCall(nativeCall nc, nativeCompCall *ncc) {
805   int i,j;
806
807
808   ncc->classname = utf_new_char(nc.classname); 
809   ncc->methCnt = nc.methCnt;
810   
811   for (i=0; i<nc.methCnt; i++) {  
812     ncc->methods[i].methodname = utf_new_char(nc.methods[i].methodname);
813     ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor);
814     ncc->callCnt[i] = nc.callCnt[i];
815
816     for (j=0; j<nc.callCnt[i]; j++) {  
817
818         ncc->methods[i].methodCalls[j].classname  = utf_new_char(nc.methods[i].methodCalls[j].classname);
819
820         if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) {
821           ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname);
822           ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor);
823           }
824         else {
825           ncc->methods[i].methodCalls[j].methodname = NULL;
826           ncc->methods[i].methodCalls[j].descriptor = NULL;
827           }
828       }
829     }
830 }
831
832
833
834 /*--------------------------------------------------------*/
835
836 bool natcall2utf(bool natcallcompdone) {
837 int i;
838
839 if (natcallcompdone) 
840         return true;
841
842 for (i=0;i<NATIVECALLSSIZE; i++) {
843    utfNativeCall  (nativeCalls[i], &nativeCompCalls[i]);  
844    }
845
846 return true;
847 }
848
849 /*--------------------------------------------------------*/
850
851
852 java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo **start)
853 {
854 #if defined(__GNUC__)
855 #warning platform dependend
856 #endif
857         java_objectarray *tmpArray;
858         int i;
859         classinfo **current;
860         classinfo *c;
861         size_t size;
862
863         size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
864
865         /*printf("end %p, start %p, size %ld\n",end,start,size);*/
866         if (!class_java_lang_Class)
867                 class_java_lang_Class = class_new(utf_new_char("java/lang/Class"));
868
869         if (!class_java_lang_SecurityManager)
870                 class_java_lang_SecurityManager =
871                         class_new(utf_new_char("java/lang/SecurityManager"));
872
873         if (size > 0) {
874                 if (start == class_java_lang_SecurityManager) {
875                         size--;
876                         start--;
877                 }
878         }
879
880         tmpArray =
881                 builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
882
883         for(i = 0, current = start; i < size; i++, current--) {
884                 c = *current;
885                 /*              printf("%d\n",i);
886                 utf_display(c->name);*/
887                 use_class_as_object(c);
888                 tmpArray->data[i] = (java_objectheader *) c;
889         }
890
891         return tmpArray;
892 }
893
894
895 java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start)
896 {
897 #if defined(__GNUC__)
898 #warning platform dependend
899 #endif
900         int i;
901         classinfo **current;
902         classinfo *c;
903         classinfo *privilegedAction;
904         size_t size;
905
906         size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
907
908         /*      log_text("builtin_asm_getclassloader");
909         printf("end %p, start %p, size %ld\n",end,start,size);*/
910
911         if (!class_java_lang_SecurityManager)
912                 class_java_lang_SecurityManager =
913                         class_new(utf_new_char("java/lang/SecurityManager"));
914
915         if (size > 0) {
916                 if (start == class_java_lang_SecurityManager) {
917                         size--;
918                         start--;
919                 }
920         }
921
922         privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
923
924         for(i = 0, current = start; i < size; i++, current--) {
925                 c = *current;
926
927                 if (c == privilegedAction)
928                         return NULL;
929
930                 if (c->classloader)
931                         return (java_lang_ClassLoader *) c->classloader;
932         }
933
934         return NULL;
935 }
936
937
938 /*
939  * These are local overrides for various environment variables in Emacs.
940  * Please do not remove this and leave it at the end of the file, where
941  * Emacs will automagically detect them.
942  * ---------------------------------------------------------------------
943  * Local variables:
944  * mode: c
945  * indent-tabs-mode: t
946  * c-basic-offset: 4
947  * tab-width: 4
948  * End:
949  */