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