* src/vm/linker.h (linker_classrenumber_mutex): Use mutex instead of java
[cacao.git] / src / vm / class.c
1 /* src/vm/class.c - class related functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "vm/types.h"
34
35 #include "arch.h"
36
37 #include "mm/memory.h"
38
39 #include "native/llni.h"
40
41 #include "threads/lock-common.h"
42 #include "threads/mutex.hpp"
43
44 #include "toolbox/logging.h"
45
46 #include "vm/array.h"
47 #include "vm/builtin.h"
48 #include "vm/class.h"
49 #include "vm/classcache.h"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/linker.h"
55 #include "vm/loader.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58
59 #if defined(ENABLE_STATISTICS)
60 # include "vm/statistics.h"
61 #endif
62
63 #include "vm/suck.h"
64 #include "vm/utf8.h"
65
66 #include "vm/jit/asmpart.h"
67
68
69 /* class_set_packagename *******************************************************
70
71    Derive the package name from the class name and store it in the
72    struct.
73
74    An internal package name consists of the package name plus the
75    trailing '/', e.g. "java/lang/".
76
77    For classes in the unnamed package, the package name is set to
78    NULL.
79
80 *******************************************************************************/
81
82 void class_set_packagename(classinfo *c)
83 {
84         char *p;
85         char *start;
86
87         p     = UTF_END(c->name) - 1;
88         start = c->name->text;
89
90         if (c->name->text[0] == '[') {
91                 /* Set packagename of arrays to the element's package. */
92
93                 for (; *start == '['; start++);
94
95                 /* Skip the 'L' in arrays of references. */
96
97                 if (*start == 'L')
98                         start++;
99         }
100
101         /* Search for last '/'. */
102
103         for (; (p > start) && (*p != '/'); --p);
104
105         /* If we found a '/' we set the package name plus the trailing
106            '/'.  Otherwise we set the packagename to NULL. */
107
108         if (p > start)
109                 c->packagename = utf_new(start, p - start + 1);
110         else
111                 c->packagename = NULL;
112 }
113
114
115 /* class_create_classinfo ******************************************************
116
117    Create a new classinfo struct. The class name is set to the given utf *,
118    most other fields are initialized to zero.
119
120    Note: classname may be NULL. In this case a not-yet-named classinfo is
121          created. The name must be filled in later and class_set_packagename
122                  must be called after that.
123
124 *******************************************************************************/
125
126 classinfo *class_create_classinfo(utf *classname)
127 {
128         classinfo *c;
129
130 #if defined(ENABLE_STATISTICS)
131         if (opt_stat)
132                 size_classinfo += sizeof(classinfo);
133 #endif
134
135         /* we use a safe name for temporarily unnamed classes */
136
137         if (classname == NULL)
138                 classname = utf_not_named_yet;
139
140 #if !defined(NDEBUG)
141         if (initverbose)
142                 log_message_utf("Creating class: ", classname);
143 #endif
144
145 #if !defined(ENABLE_GC_BOEHM)
146         c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
147         /*c = NEW(classinfo);
148         MZERO(c, classinfo, 1);*/
149 #else
150         c = GCNEW_UNCOLLECTABLE(classinfo, 1);
151         /* GCNEW_UNCOLLECTABLE clears the allocated memory */
152 #endif
153
154         c->name = classname;
155
156         /* Set the header.vftbl of all loaded classes to the one of
157        java.lang.Class, so Java code can use a class as object. */
158
159         if (class_java_lang_Class != NULL)
160                 if (class_java_lang_Class->vftbl != NULL)
161                         c->object.header.vftbl = class_java_lang_Class->vftbl;
162
163 #if defined(ENABLE_JAVASE)
164         /* check if the class is a reference class and flag it */
165
166         if (classname == utf_java_lang_ref_SoftReference) {
167                 c->flags |= ACC_CLASS_REFERENCE_SOFT;
168         }
169         else if (classname == utf_java_lang_ref_WeakReference) {
170                 c->flags |= ACC_CLASS_REFERENCE_WEAK;
171         }
172         else if (classname == utf_java_lang_ref_PhantomReference) {
173                 c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
174         }
175 #endif
176
177         if (classname != utf_not_named_yet)
178                 class_set_packagename(c);
179
180         LOCK_INIT_OBJECT_LOCK(&c->object.header);
181
182         return c;
183 }
184
185
186 /* class_postset_header_vftbl **************************************************
187
188    Set the header.vftbl of all classes created before java.lang.Class
189    was linked.  This is necessary that Java code can use a class as
190    object.
191
192 *******************************************************************************/
193
194 void class_postset_header_vftbl(void)
195 {
196         classinfo *c;
197         u4 slot;
198         classcache_name_entry *nmen;
199         classcache_class_entry *clsen;
200
201         assert(class_java_lang_Class);
202
203         for (slot = 0; slot < hashtable_classcache.size; slot++) {
204                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
205
206                 for (; nmen; nmen = nmen->hashlink) {
207                         /* iterate over all class entries */
208
209                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
210                                 c = clsen->classobj;
211
212                                 /* now set the the vftbl */
213
214                                 if (c->object.header.vftbl == NULL)
215                                         c->object.header.vftbl = class_java_lang_Class->vftbl;
216                         }
217                 }
218         }
219 }
220
221 /* class_define ****************************************************************
222
223    Calls the loader and defines a class in the VM.
224
225 *******************************************************************************/
226
227 classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
228 {
229         classinfo   *c;
230         classinfo   *r;
231         classbuffer *cb;
232
233         if (name != NULL) {
234                 /* check if this class has already been defined */
235
236                 c = classcache_lookup_defined_or_initiated(cl, name);
237
238                 if (c != NULL) {
239                         exceptions_throw_linkageerror("duplicate class definition: ", c);
240                         return NULL;
241                 }
242         } 
243
244         /* create a new classinfo struct */
245
246         c = class_create_classinfo(name);
247
248 #if defined(ENABLE_STATISTICS)
249         /* measure time */
250
251         if (opt_getloadingtime)
252                 loadingtime_start();
253 #endif
254
255         /* build a classbuffer with the given data */
256
257         cb = NEW(classbuffer);
258
259         cb->clazz = c;
260         cb->size  = length;
261         cb->data  = data;
262         cb->pos   = cb->data;
263
264         /* preset the defining classloader */
265
266         c->classloader = cl;
267
268         /* load the class from this buffer */
269
270         r = load_class_from_classbuffer(cb);
271
272         /* free memory */
273
274         FREE(cb, classbuffer);
275
276 #if defined(ENABLE_STATISTICS)
277         /* measure time */
278
279         if (opt_getloadingtime)
280                 loadingtime_stop();
281 #endif
282
283         if (r == NULL) {
284                 /* If return value is NULL, we had a problem and the class is
285                    not loaded.  Now free the allocated memory, otherwise we
286                    could run into a DOS. */
287
288                 class_free(c);
289
290                 return NULL;
291         }
292
293 #if defined(ENABLE_JAVASE)
294 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
295         /* Store the protection domain. */
296
297         c->protectiondomain = pd;
298 # endif
299 #endif
300
301         /* Store the newly defined class in the class cache. This call
302            also checks whether a class of the same name has already been
303            defined by the same defining loader, and if so, replaces the
304            newly created class by the one defined earlier. */
305
306         /* Important: The classinfo given to classcache_store must be
307                       fully prepared because another thread may return
308                       this pointer after the lookup at to top of this
309                       function directly after the class cache lock has
310                       been released. */
311
312         c = classcache_store(cl, c, true);
313
314         return c;
315 }
316
317
318 /* class_load_attribute_sourcefile *********************************************
319
320    SourceFile_attribute {
321        u2 attribute_name_index;
322        u4 attribute_length;
323            u2 sourcefile_index;
324    }
325
326 *******************************************************************************/
327
328 static bool class_load_attribute_sourcefile(classbuffer *cb)
329 {
330         classinfo *c;
331         u4         attribute_length;
332         u2         sourcefile_index;
333         utf       *sourcefile;
334
335         /* get classinfo */
336
337         c = cb->clazz;
338
339         /* check buffer size */
340
341         if (!suck_check_classbuffer_size(cb, 4 + 2))
342                 return false;
343
344         /* check attribute length */
345
346         attribute_length = suck_u4(cb);
347
348         if (attribute_length != 2) {
349                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
350                 return false;
351         }
352
353         /* there can be no more than one SourceFile attribute */
354
355         if (c->sourcefile != NULL) {
356                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
357                 return false;
358         }
359
360         /* get sourcefile */
361
362         sourcefile_index = suck_u2(cb);
363         sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
364
365         if (sourcefile == NULL)
366                 return false;
367
368         /* store sourcefile */
369
370         c->sourcefile = sourcefile;
371
372         return true;
373 }
374
375
376 /* class_load_attribute_enclosingmethod ****************************************
377
378    EnclosingMethod_attribute {
379        u2 attribute_name_index;
380        u4 attribute_length;
381            u2 class_index;
382            u2 method_index;
383    }
384
385 *******************************************************************************/
386
387 #if defined(ENABLE_JAVASE)
388 static bool class_load_attribute_enclosingmethod(classbuffer *cb)
389 {
390         classinfo             *c;
391         u4                     attribute_length;
392         u2                     class_index;
393         u2                     method_index;
394         classref_or_classinfo  cr;
395         constant_nameandtype  *cn;
396
397         /* get classinfo */
398
399         c = cb->clazz;
400
401         /* check buffer size */
402
403         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
404                 return false;
405
406         /* check attribute length */
407
408         attribute_length = suck_u4(cb);
409
410         if (attribute_length != 4) {
411                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
412                 return false;
413         }
414
415         /* there can be no more than one EnclosingMethod attribute */
416
417         if (c->enclosingmethod != NULL) {
418                 exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
419                 return false;
420         }
421
422         /* get class index */
423
424         class_index = suck_u2(cb);
425         cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
426
427         /* get method index */
428
429         method_index = suck_u2(cb);
430         cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
431
432         /* store info in classinfo */
433
434         c->enclosingclass.any = cr.any;
435         c->enclosingmethod    = cn;
436
437         return true;
438 }
439 #endif /* defined(ENABLE_JAVASE) */
440
441
442 /* class_load_attributes *******************************************************
443
444    Read attributes from ClassFile.
445
446    attribute_info {
447        u2 attribute_name_index;
448        u4 attribute_length;
449        u1 info[attribute_length];
450    }
451
452    InnerClasses_attribute {
453        u2 attribute_name_index;
454        u4 attribute_length;
455    }
456
457 *******************************************************************************/
458
459 bool class_load_attributes(classbuffer *cb)
460 {
461         classinfo             *c;
462         uint16_t               attributes_count;
463         uint16_t               attribute_name_index;
464         utf                   *attribute_name;
465         innerclassinfo        *info;
466         classref_or_classinfo  inner;
467         classref_or_classinfo  outer;
468         utf                   *name;
469         uint16_t               flags;
470         int                    i, j;
471
472         c = cb->clazz;
473
474         /* get attributes count */
475
476         if (!suck_check_classbuffer_size(cb, 2))
477                 return false;
478
479         attributes_count = suck_u2(cb);
480
481         for (i = 0; i < attributes_count; i++) {
482                 /* get attribute name */
483
484                 if (!suck_check_classbuffer_size(cb, 2))
485                         return false;
486
487                 attribute_name_index = suck_u2(cb);
488                 attribute_name =
489                         class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
490
491                 if (attribute_name == NULL)
492                         return false;
493
494                 if (attribute_name == utf_InnerClasses) {
495                         /* InnerClasses */
496
497                         if (c->innerclass != NULL) {
498                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
499                                 return false;
500                         }
501                                 
502                         if (!suck_check_classbuffer_size(cb, 4 + 2))
503                                 return false;
504
505                         /* skip attribute length */
506                         suck_u4(cb);
507
508                         /* number of records */
509                         c->innerclasscount = suck_u2(cb);
510
511                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
512                                 return false;
513
514                         /* allocate memory for innerclass structure */
515                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
516
517                         for (j = 0; j < c->innerclasscount; j++) {
518                                 /* The innerclass structure contains a class with an encoded
519                                    name, its defining scope, its simple name and a bitmask of
520                                    the access flags. */
521                                                                 
522                                 info = c->innerclass + j;
523
524                                 inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
525                                 outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
526                                 name      = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
527                                 flags     = suck_u2(cb);
528
529                                 /* If the current inner-class is the currently loaded
530                                    class check for some special flags. */
531
532                                 if (inner.ref->name == c->name) {
533                                         /* If an inner-class is not a member, its
534                                            outer-class is NULL. */
535
536                                         if (outer.ref != NULL) {
537                                                 c->flags |= ACC_CLASS_MEMBER;
538
539                                                 /* A member class doesn't have an
540                                                    EnclosingMethod attribute, so set the
541                                                    enclosing-class to be the same as the
542                                                    declaring-class. */
543
544                                                 c->declaringclass = outer;
545                                                 c->enclosingclass = outer;
546                                         }
547
548                                         /* If an inner-class is anonymous, its name is
549                                            NULL. */
550
551                                         if (name == NULL)
552                                                 c->flags |= ACC_CLASS_ANONYMOUS;
553                                 }
554
555                                 info->inner_class = inner;
556                                 info->outer_class = outer;
557                                 info->name        = name;
558                                 info->flags       = flags;
559                         }
560                 }
561                 else if (attribute_name == utf_SourceFile) {
562                         /* SourceFile */
563
564                         if (!class_load_attribute_sourcefile(cb))
565                                 return false;
566                 }
567 #if defined(ENABLE_JAVASE)
568                 else if (attribute_name == utf_EnclosingMethod) {
569                         /* EnclosingMethod */
570
571                         if (!class_load_attribute_enclosingmethod(cb))
572                                 return false;
573                 }
574                 else if (attribute_name == utf_Signature) {
575                         /* Signature */
576
577                         if (!loader_load_attribute_signature(cb, &(c->signature)))
578                                 return false;
579                 }
580 #endif
581
582 #if defined(ENABLE_ANNOTATIONS)
583                 else if (attribute_name == utf_RuntimeVisibleAnnotations) {
584                         /* RuntimeVisibleAnnotations */
585                         if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
586                                 return false;
587                 }
588                 else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
589                         /* RuntimeInvisibleAnnotations */
590                         if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
591                                 return false;
592                 }
593 #endif
594
595                 else {
596                         /* unknown attribute */
597
598                         if (!loader_skip_attribute_body(cb))
599                                 return false;
600                 }
601         }
602
603         return true;
604 }
605
606
607 /* class_freepool **************************************************************
608
609         Frees all resources used by this classes Constant Pool.
610
611 *******************************************************************************/
612
613 static void class_freecpool(classinfo *c)
614 {
615         u4 idx;
616         u4 tag;
617         void* info;
618         
619         if (c->cptags && c->cpinfos) {
620                 for (idx = 0; idx < c->cpcount; idx++) {
621                         tag = c->cptags[idx];
622                         info = c->cpinfos[idx];
623                 
624                         if (info != NULL) {
625                                 switch (tag) {
626                                 case CONSTANT_Fieldref:
627                                 case CONSTANT_Methodref:
628                                 case CONSTANT_InterfaceMethodref:
629                                         FREE(info, constant_FMIref);
630                                         break;
631                                 case CONSTANT_Integer:
632                                         FREE(info, constant_integer);
633                                         break;
634                                 case CONSTANT_Float:
635                                         FREE(info, constant_float);
636                                         break;
637                                 case CONSTANT_Long:
638                                         FREE(info, constant_long);
639                                         break;
640                                 case CONSTANT_Double:
641                                         FREE(info, constant_double);
642                                         break;
643                                 case CONSTANT_NameAndType:
644                                         FREE(info, constant_nameandtype);
645                                         break;
646                                 }
647                         }
648                 }
649         }
650
651         if (c->cptags)
652                 MFREE(c->cptags, u1, c->cpcount);
653
654         if (c->cpinfos)
655                 MFREE(c->cpinfos, void*, c->cpcount);
656 }
657
658
659 /* class_getconstant ***********************************************************
660
661    Retrieves the value at position 'pos' of the constantpool of a
662    class. If the type of the value is other than 'ctype', an error is
663    thrown.
664
665 *******************************************************************************/
666
667 void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
668 {
669         /* check index and type of constantpool entry */
670         /* (pos == 0 is caught by type comparison) */
671
672         if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
673                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
674                 return NULL;
675         }
676
677         return c->cpinfos[pos];
678 }
679
680
681 /* innerclass_getconstant ******************************************************
682
683    Like class_getconstant, but if cptags is ZERO, null is returned.
684         
685 *******************************************************************************/
686
687 void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
688 {
689         /* invalid position in constantpool */
690
691         if (pos >= c->cpcount) {
692                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
693                 return NULL;
694         }
695
696         /* constantpool entry of type 0 */      
697
698         if (c->cptags[pos] == 0)
699                 return NULL;
700
701         /* check type of constantpool entry */
702
703         if (c->cptags[pos] != ctype) {
704                 exceptions_throw_classformaterror(c, "Illegal constant pool index");
705                 return NULL;
706         }
707                 
708         return c->cpinfos[pos];
709 }
710
711
712 /* class_free ******************************************************************
713
714    Frees all resources used by the class.
715
716 *******************************************************************************/
717
718 void class_free(classinfo *c)
719 {
720         s4 i;
721         vftbl_t *v;
722
723         class_freecpool(c);
724
725         if (c->interfaces != NULL)
726                 MFREE(c->interfaces, classinfo*, c->interfacescount);
727
728         if (c->fields) {
729                 for (i = 0; i < c->fieldscount; i++)
730                         field_free(&(c->fields[i]));
731                 MFREE(c->fields, fieldinfo, c->fieldscount);
732         }
733         
734         if (c->methods) {
735                 for (i = 0; i < c->methodscount; i++)
736                         method_free(&(c->methods[i]));
737                 MFREE(c->methods, methodinfo, c->methodscount);
738         }
739
740         if ((v = c->vftbl) != NULL) {
741                 if (v->arraydesc)
742                         mem_free(v->arraydesc,sizeof(arraydescriptor));
743                 
744                 for (i = 0; i < v->interfacetablelength; i++) {
745                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
746                 }
747                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
748
749                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
750                     sizeof(methodptr*) * (v->interfacetablelength -
751                                          (v->interfacetablelength > 0));
752                 v = (vftbl_t*) (((methodptr*) v) -
753                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
754                 mem_free(v, i);
755         }
756
757         if (c->innerclass)
758                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
759
760         /*      if (c->classvftbl)
761                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
762         
763 /*      GCFREE(c); */
764 }
765
766
767 /* get_array_class *************************************************************
768
769    Returns the array class with the given name for the given
770    classloader, or NULL if an exception occurred.
771
772    Note: This function does eager loading. 
773
774 *******************************************************************************/
775
776 static classinfo *get_array_class(utf *name,classloader_t *initloader,
777                                                                                         classloader_t *defloader,bool link)
778 {
779         classinfo *c;
780         
781         /* lookup this class in the classcache */
782         c = classcache_lookup(initloader,name);
783         if (!c)
784                 c = classcache_lookup_defined(defloader,name);
785
786         if (!c) {
787                 /* we have to create it */
788                 c = class_create_classinfo(name);
789                 c = load_newly_created_array(c,initloader);
790                 if (c == NULL)
791                         return NULL;
792         }
793
794         assert(c);
795         assert(c->state & CLASS_LOADED);
796         assert(c->classloader == defloader);
797
798         if (link && !(c->state & CLASS_LINKED))
799                 if (!link_class(c))
800                         return NULL;
801
802         assert(!link || (c->state & CLASS_LINKED));
803
804         return c;
805 }
806
807
808 /* class_array_of **************************************************************
809
810    Returns an array class with the given component class. The array
811    class is dynamically created if neccessary.
812
813 *******************************************************************************/
814
815 classinfo *class_array_of(classinfo *component, bool link)
816 {
817         classloader_t     *cl;
818     s4                 namelen;
819     char              *namebuf;
820         utf               *u;
821         classinfo         *c;
822         int32_t            dumpmarker;
823
824         cl = component->classloader;
825
826         DMARKER;
827
828     /* Assemble the array class name */
829     namelen = component->name->blength;
830     
831     if (component->name->text[0] == '[') {
832         /* the component is itself an array */
833         namebuf = DMNEW(char, namelen + 1);
834         namebuf[0] = '[';
835         MCOPY(namebuf + 1, component->name->text, char, namelen);
836         namelen++;
837     }
838         else {
839         /* the component is a non-array class */
840         namebuf = DMNEW(char, namelen + 3);
841         namebuf[0] = '[';
842         namebuf[1] = 'L';
843         MCOPY(namebuf + 2, component->name->text, char, namelen);
844         namebuf[2 + namelen] = ';';
845         namelen += 3;
846     }
847
848         u = utf_new(namebuf, namelen);
849
850         c = get_array_class(u, cl, cl, link);
851
852         DRELEASE;
853
854         return c;
855 }
856
857
858 /* class_multiarray_of *********************************************************
859
860    Returns an array class with the given dimension and element class.
861    The array class is dynamically created if neccessary.
862
863 *******************************************************************************/
864
865 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
866 {
867     s4 namelen;
868     char *namebuf;
869         classinfo *c;
870         int32_t    dumpmarker;
871
872         DMARKER;
873
874         if (dim < 1) {
875                 log_text("Invalid array dimension requested");
876                 assert(0);
877         }
878
879     /* Assemble the array class name */
880     namelen = element->name->blength;
881     
882     if (element->name->text[0] == '[') {
883         /* the element is itself an array */
884         namebuf = DMNEW(char, namelen + dim);
885         memcpy(namebuf + dim, element->name->text, namelen);
886         namelen += dim;
887     }
888     else {
889         /* the element is a non-array class */
890         namebuf = DMNEW(char, namelen + 2 + dim);
891         namebuf[dim] = 'L';
892         memcpy(namebuf + dim + 1, element->name->text, namelen);
893         namelen += (2 + dim);
894         namebuf[namelen - 1] = ';';
895     }
896         memset(namebuf, '[', dim);
897
898         c = get_array_class(utf_new(namebuf, namelen),
899                                                 element->classloader,
900                                                 element->classloader,
901                                                 link);
902
903         DRELEASE;
904
905         return c;
906 }
907
908
909 /* class_lookup_classref *******************************************************
910
911    Looks up the constant_classref for a given classname in the classref
912    tables of a class.
913
914    IN:
915        cls..............the class containing the reference
916            name.............the name of the class refered to
917
918     RETURN VALUE:
919            a pointer to a constant_classref, or 
920            NULL if the reference was not found
921    
922 *******************************************************************************/
923
924 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
925 {
926         constant_classref *ref;
927         extra_classref *xref;
928         int count;
929
930         assert(cls);
931         assert(name);
932         assert(!cls->classrefcount || cls->classrefs);
933         
934         /* first search the main classref table */
935         count = cls->classrefcount;
936         ref = cls->classrefs;
937         for (; count; --count, ++ref)
938                 if (ref->name == name)
939                         return ref;
940
941         /* next try the list of extra classrefs */
942         for (xref = cls->extclassrefs; xref; xref = xref->next) {
943                 if (xref->classref.name == name)
944                         return &(xref->classref);
945         }
946
947         /* not found */
948         return NULL;
949 }
950
951
952 /* class_get_classref **********************************************************
953
954    Returns the constant_classref for a given classname.
955
956    IN:
957        cls..............the class containing the reference
958            name.............the name of the class refered to
959
960    RETURN VALUE:
961        a pointer to a constant_classref (never NULL)
962
963    NOTE:
964        The given name is not checked for validity!
965    
966 *******************************************************************************/
967
968 constant_classref *class_get_classref(classinfo *cls, utf *name)
969 {
970         constant_classref *ref;
971         extra_classref *xref;
972
973         assert(cls);
974         assert(name);
975
976         ref = class_lookup_classref(cls,name);
977         if (ref)
978                 return ref;
979
980         xref = NEW(extra_classref);
981         CLASSREF_INIT(xref->classref,cls,name);
982
983         xref->next = cls->extclassrefs;
984         cls->extclassrefs = xref;
985
986         return &(xref->classref);
987 }
988
989
990 /* class_get_self_classref *****************************************************
991
992    Returns the constant_classref to the class itself.
993
994    IN:
995        cls..............the class containing the reference
996
997    RETURN VALUE:
998        a pointer to a constant_classref (never NULL)
999
1000 *******************************************************************************/
1001
1002 constant_classref *class_get_self_classref(classinfo *cls)
1003 {
1004         /* XXX this should be done in a faster way. Maybe always make */
1005         /* the classref of index 0 a self reference.                  */
1006         return class_get_classref(cls,cls->name);
1007 }
1008
1009 /* class_get_classref_multiarray_of ********************************************
1010
1011    Returns an array type reference with the given dimension and element class
1012    reference.
1013
1014    IN:
1015        dim..............the requested dimension
1016                             dim must be in [1;255]. This is NOT checked!
1017            ref..............the component class reference
1018
1019    RETURN VALUE:
1020        a pointer to the class reference for the array type
1021
1022    NOTE:
1023        The referer of `ref` is used as the referer for the new classref.
1024
1025 *******************************************************************************/
1026
1027 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1028 {
1029     s4 namelen;
1030     char *namebuf;
1031         constant_classref *cr;
1032         int32_t            dumpmarker;
1033
1034         assert(ref);
1035         assert(dim >= 1 && dim <= 255);
1036
1037         DMARKER;
1038
1039     /* Assemble the array class name */
1040     namelen = ref->name->blength;
1041     
1042     if (ref->name->text[0] == '[') {
1043         /* the element is itself an array */
1044         namebuf = DMNEW(char, namelen + dim);
1045         memcpy(namebuf + dim, ref->name->text, namelen);
1046         namelen += dim;
1047     }
1048     else {
1049         /* the element is a non-array class */
1050         namebuf = DMNEW(char, namelen + 2 + dim);
1051         namebuf[dim] = 'L';
1052         memcpy(namebuf + dim + 1, ref->name->text, namelen);
1053         namelen += (2 + dim);
1054         namebuf[namelen - 1] = ';';
1055     }
1056         memset(namebuf, '[', dim);
1057
1058     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
1059
1060         DRELEASE;
1061
1062         return cr;
1063 }
1064
1065
1066 /* class_get_classref_component_of *********************************************
1067
1068    Returns the component classref of a given array type reference
1069
1070    IN:
1071        ref..............the array type reference
1072
1073    RETURN VALUE:
1074        a reference to the component class, or
1075            NULL if `ref` is not an object array type reference
1076
1077    NOTE:
1078        The referer of `ref` is used as the referer for the new classref.
1079
1080 *******************************************************************************/
1081
1082 constant_classref *class_get_classref_component_of(constant_classref *ref)
1083 {
1084         s4 namelen;
1085         char *name;
1086         
1087         assert(ref);
1088
1089         name = ref->name->text;
1090         if (*name++ != '[')
1091                 return NULL;
1092         
1093         namelen = ref->name->blength - 1;
1094         if (*name == 'L') {
1095                 name++;
1096                 namelen -= 2;
1097         }
1098         else if (*name != '[') {
1099                 return NULL;
1100         }
1101
1102     return class_get_classref(ref->referer, utf_new(name, namelen));
1103 }
1104
1105
1106 /* class_findmethod ************************************************************
1107         
1108    Searches a 'classinfo' structure for a method having the given name
1109    and descriptor. If descriptor is NULL, it is ignored.
1110
1111 *******************************************************************************/
1112
1113 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1114 {
1115         methodinfo *m;
1116         s4          i;
1117
1118         for (i = 0; i < c->methodscount; i++) {
1119                 m = &(c->methods[i]);
1120
1121                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1122                         return m;
1123         }
1124
1125         return NULL;
1126 }
1127
1128
1129 /* class_resolvemethod *********************************************************
1130         
1131    Searches a class and it's super classes for a method.
1132
1133    Superinterfaces are *not* searched.
1134
1135 *******************************************************************************/
1136
1137 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1138 {
1139         methodinfo *m;
1140
1141         while (c) {
1142                 m = class_findmethod(c, name, desc);
1143
1144                 if (m)
1145                         return m;
1146
1147                 /* JVM Specification bug: 
1148
1149                    It is important NOT to resolve special <init> and <clinit>
1150                    methods to super classes or interfaces; yet, this is not
1151                    explicited in the specification.  Section 5.4.3.3 should be
1152                    updated appropriately.  */
1153
1154                 if (name == utf_init || name == utf_clinit)
1155                         return NULL;
1156
1157                 c = c->super;
1158         }
1159
1160         return NULL;
1161 }
1162
1163
1164 /* class_resolveinterfacemethod_intern *****************************************
1165
1166    Internally used helper function. Do not use this directly.
1167
1168 *******************************************************************************/
1169
1170 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1171                                                                                                            utf *name, utf *desc)
1172 {
1173         methodinfo *m;
1174         s4          i;
1175
1176         /* try to find the method in the class */
1177
1178         m = class_findmethod(c, name, desc);
1179
1180         if (m != NULL)
1181                 return m;
1182
1183         /* No method found?  Try the super interfaces. */
1184
1185         for (i = 0; i < c->interfacescount; i++) {
1186                 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1187
1188                 if (m != NULL)
1189                         return m;
1190         }
1191
1192         /* no method found */
1193
1194         return NULL;
1195 }
1196
1197
1198 /* class_resolveclassmethod ****************************************************
1199         
1200    Resolves a reference from REFERER to a method with NAME and DESC in
1201    class C.
1202
1203    If the method cannot be resolved the return value is NULL. If
1204    EXCEPT is true *exceptionptr is set, too.
1205
1206 *******************************************************************************/
1207
1208 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1209                                                                          classinfo *referer, bool throwexception)
1210 {
1211         classinfo  *cls;
1212         methodinfo *m;
1213         s4          i;
1214
1215 /*      if (c->flags & ACC_INTERFACE) { */
1216 /*              if (throwexception) */
1217 /*                      *exceptionptr = */
1218 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1219 /*              return NULL; */
1220 /*      } */
1221
1222         /* try class c and its superclasses */
1223
1224         cls = c;
1225
1226         m = class_resolvemethod(cls, name, desc);
1227
1228         if (m != NULL)
1229                 goto found;
1230
1231         /* Try the super interfaces. */
1232
1233         for (i = 0; i < c->interfacescount; i++) {
1234                 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1235
1236                 if (m != NULL)
1237                         goto found;
1238         }
1239         
1240         if (throwexception)
1241                 exceptions_throw_nosuchmethoderror(c, name, desc);
1242
1243         return NULL;
1244
1245  found:
1246         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1247                 if (throwexception)
1248                         exceptions_throw_abstractmethoderror();
1249
1250                 return NULL;
1251         }
1252
1253         /* XXX check access rights */
1254
1255         return m;
1256 }
1257
1258
1259 /* class_resolveinterfacemethod ************************************************
1260
1261    Resolves a reference from REFERER to a method with NAME and DESC in
1262    interface C.
1263
1264    If the method cannot be resolved the return value is NULL. If
1265    EXCEPT is true *exceptionptr is set, too.
1266
1267 *******************************************************************************/
1268
1269 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1270                                                                                  classinfo *referer, bool throwexception)
1271 {
1272         methodinfo *mi;
1273
1274         if (!(c->flags & ACC_INTERFACE)) {
1275                 if (throwexception)
1276                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1277
1278                 return NULL;
1279         }
1280
1281         mi = class_resolveinterfacemethod_intern(c, name, desc);
1282
1283         if (mi != NULL)
1284                 return mi;
1285
1286         /* try class java.lang.Object */
1287
1288         mi = class_findmethod(class_java_lang_Object, name, desc);
1289
1290         if (mi != NULL)
1291                 return mi;
1292
1293         if (throwexception)
1294                 exceptions_throw_nosuchmethoderror(c, name, desc);
1295
1296         return NULL;
1297 }
1298
1299
1300 /* class_findfield *************************************************************
1301         
1302    Searches for field with specified name and type in a classinfo
1303    structure. If no such field is found NULL is returned.
1304
1305 *******************************************************************************/
1306
1307 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1308 {
1309         s4 i;
1310
1311         for (i = 0; i < c->fieldscount; i++)
1312                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1313                         return &(c->fields[i]);
1314
1315         if (c->super != NULL)
1316                 return class_findfield(c->super, name, desc);
1317
1318         return NULL;
1319 }
1320
1321
1322 /* class_findfield_approx ******************************************************
1323         
1324    Searches in 'classinfo'-structure for a field with the specified
1325    name.
1326
1327 *******************************************************************************/
1328  
1329 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1330 {
1331         for (int32_t i = 0; i < c->fieldscount; i++) {
1332                 fieldinfo* f = &(c->fields[i]);
1333
1334                 if (f->name == name)
1335                         return f;
1336         }
1337
1338         // Field not found.
1339         exceptions_throw_nosuchfielderror(c, name);
1340         return NULL;
1341 }
1342
1343
1344 /****************** Function: class_resolvefield_int ***************************
1345
1346     This is an internally used helper function. Do not use this directly.
1347
1348         Tries to resolve a field having the given name and type.
1349     If the field cannot be resolved, NULL is returned.
1350
1351 *******************************************************************************/
1352
1353 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1354 {
1355         fieldinfo *fi;
1356         s4         i;
1357
1358         /* search for field in class c */
1359
1360         for (i = 0; i < c->fieldscount; i++) { 
1361                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1362                         return &(c->fields[i]);
1363                 }
1364     }
1365
1366         /* Try super interfaces recursively. */
1367
1368         for (i = 0; i < c->interfacescount; i++) {
1369                 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1370
1371                 if (fi != NULL)
1372                         return fi;
1373         }
1374
1375         /* Try super class. */
1376
1377         if (c->super != NULL)
1378                 return class_resolvefield_int(c->super, name, desc);
1379
1380         /* not found */
1381
1382         return NULL;
1383 }
1384
1385
1386 /********************* Function: class_resolvefield ***************************
1387         
1388         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1389
1390     If the field cannot be resolved, an exception is thrown and the
1391     return value is NULL.
1392
1393 *******************************************************************************/
1394
1395 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1396 {
1397         fieldinfo *fi;
1398
1399         fi = class_resolvefield_int(c, name, desc);
1400
1401         if (!fi) {
1402                 exceptions_throw_nosuchfielderror(c, name);
1403                 return NULL;
1404         }
1405
1406         /* XXX check access rights */
1407
1408         return fi;
1409 }
1410
1411
1412 /* class_issubclass ************************************************************
1413
1414    Checks if sub is a descendant of super.
1415         
1416 *******************************************************************************/
1417
1418 bool class_issubclass(classinfo *sub, classinfo *super)
1419 {
1420         classinfo *c;
1421
1422         c = sub;
1423
1424         for (;;) {
1425                 /* We reached java/lang/Object and did not find the requested
1426                    super class. */
1427
1428                 if (c == NULL)
1429                         return false;
1430
1431                 /* We found the requested super class. */
1432
1433                 if (c == super)
1434                         return true;
1435
1436                 c = c->super;
1437         }
1438 }
1439
1440
1441 /* class_isanysubclass *********************************************************
1442
1443    Checks a subclass relation between two classes. Implemented
1444    interfaces are interpreted as super classes.
1445
1446    Return value: 1 ... sub is subclass of super
1447                  0 ... otherwise
1448
1449 *******************************************************************************/
1450
1451 bool class_isanysubclass(classinfo *sub, classinfo *super)
1452 {
1453         uint32_t diffval;
1454         bool     result;
1455
1456         /* This is the trivial case. */
1457
1458         if (sub == super)
1459                 return true;
1460
1461         /* Primitive classes are only subclasses of themselves. */
1462
1463         if (class_is_primitive(sub) || class_is_primitive(super))
1464                 return false;
1465
1466         /* Check for interfaces. */
1467
1468         if (super->flags & ACC_INTERFACE) {
1469                 result = (sub->vftbl->interfacetablelength > super->index) &&
1470                         (sub->vftbl->interfacetable[-super->index] != NULL);
1471         }
1472         else {
1473                 /* java.lang.Object is the only super class of any
1474                    interface. */
1475
1476                 if (sub->flags & ACC_INTERFACE)
1477                         return (super == class_java_lang_Object);
1478
1479                 Mutex_lock(linker_classrenumber_mutex);
1480
1481                 diffval = sub->vftbl->baseval - super->vftbl->baseval;
1482                 result  = diffval <= (uint32_t) super->vftbl->diffval;
1483
1484                 Mutex_unlock(linker_classrenumber_mutex);
1485         }
1486
1487         return result;
1488 }
1489
1490
1491 /* class_is_assignable_from ****************************************************
1492
1493    Return whether an instance of the "from" class parameter would be
1494    an instance of this class "to" as well.
1495
1496    ARGUMENTS:
1497        to ..... class
1498            from ... class
1499
1500    RETURN:
1501        true .... is assignable
1502            false ... is not assignable
1503
1504 *******************************************************************************/
1505
1506 bool class_is_assignable_from(classinfo *to, classinfo *from)
1507 {
1508         if (!(to->state & CLASS_LINKED))
1509                 if (!link_class(to))
1510                         return false;
1511
1512         if (!(from->state & CLASS_LINKED))
1513                 if (!link_class(from))
1514                         return false;
1515
1516         return class_isanysubclass(from, to);
1517 }
1518
1519
1520 /* class_is_instance ***********************************************************
1521
1522    Return if the given Java object is an instance of the given class.
1523
1524    ARGUMENTS:
1525        c ... class
1526            h ... Java object
1527
1528    RETURN:
1529        true .... is instance
1530            false ... is not instance
1531
1532 *******************************************************************************/
1533
1534 bool class_is_instance(classinfo *c, java_handle_t *h)
1535 {
1536         if (!(c->state & CLASS_LINKED))
1537                 if (!link_class(c))
1538                         return false;
1539
1540         return builtin_instanceof(h, c);
1541 }
1542
1543
1544 /* class_get_componenttype *****************************************************
1545
1546    Return the component class of the given class.  If the given class
1547    is not an array, return NULL.
1548
1549 *******************************************************************************/
1550
1551 classinfo *class_get_componenttype(classinfo *c)
1552 {
1553         classinfo       *component;
1554         arraydescriptor *ad;
1555         
1556         /* XXX maybe we could find a way to do this without linking. */
1557         /* This way should be safe and easy, however.                */
1558
1559         if (!(c->state & CLASS_LINKED))
1560                 if (!link_class(c))
1561                         return NULL;
1562
1563         ad = c->vftbl->arraydesc;
1564         
1565         if (ad == NULL)
1566                 return NULL;
1567         
1568         if (ad->arraytype == ARRAYTYPE_OBJECT)
1569                 component = ad->componentvftbl->clazz;
1570         else
1571                 component = Primitive_get_class_by_type(ad->arraytype);
1572                 
1573         return component;
1574 }
1575
1576
1577 /* class_get_declaredclasses ***************************************************
1578
1579    Return an array of declared classes of the given class.
1580
1581 *******************************************************************************/
1582
1583 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1584 {
1585         classref_or_classinfo  inner;
1586         classref_or_classinfo  outer;
1587         utf                   *outername;
1588         int                    declaredclasscount;  /* number of declared classes */
1589         int                    pos;                     /* current declared class */
1590         java_handle_objectarray_t *oa;               /* array of declared classes */
1591         int                    i;
1592         classinfo             *ic;
1593
1594         declaredclasscount = 0;
1595
1596         if (!class_is_primitive(c) && !class_is_array(c)) {
1597                 /* Determine number of declared classes. */
1598
1599                 for (i = 0; i < c->innerclasscount; i++) {
1600                         /* Get outer-class.  If the inner-class is not a member
1601                            class, the outer-class is NULL. */
1602
1603                         outer = c->innerclass[i].outer_class;
1604
1605                         if (outer.any == NULL)
1606                                 continue;
1607
1608                         /* Check if outer-class is a classref or a real class and
1609                get the class name from the structure. */
1610
1611                         outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1612
1613                         /* Outer class is this class. */
1614
1615                         if ((outername == c->name) &&
1616                                 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1617                                 declaredclasscount++;
1618                 }
1619         }
1620
1621         /* Allocate Class[] and check for OOM. */
1622
1623         oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1624
1625         if (oa == NULL)
1626                 return NULL;
1627
1628         for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1629                 inner = c->innerclass[i].inner_class;
1630                 outer = c->innerclass[i].outer_class;
1631
1632                 /* Get outer-class.  If the inner-class is not a member class,
1633                    the outer-class is NULL. */
1634
1635                 if (outer.any == NULL)
1636                         continue;
1637
1638                 /* Check if outer_class is a classref or a real class and get
1639                    the class name from the structure. */
1640
1641                 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1642
1643                 /* Outer class is this class. */
1644
1645                 if ((outername == c->name) &&
1646                         ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1647
1648                         ic = resolve_classref_or_classinfo_eager(inner, false);
1649
1650                         if (ic == NULL)
1651                                 return NULL;
1652
1653                         if (!(ic->state & CLASS_LINKED))
1654                                 if (!link_class(ic))
1655                                         return NULL;
1656
1657                         LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1658                 }
1659         }
1660
1661         return oa;
1662 }
1663
1664
1665 /**
1666  * Return an array of declared constructors of the given class.
1667  *
1668  * @param c          class to get the constructors of
1669  * @param publicOnly show only public fields
1670  *
1671  * @return array of java.lang.reflect.Constructor
1672  */
1673 #if defined(ENABLE_JAVASE)
1674 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1675 {
1676         methodinfo*                m;
1677         java_handle_objectarray_t* oa;
1678         java_handle_t*             rc;
1679         int                        count;
1680         int                        index;
1681         int                        i;
1682
1683         /* Determine number of constructors. */
1684
1685         count = 0;
1686
1687         for (i = 0; i < c->methodscount; i++) {
1688                 m = &(c->methods[i]);
1689
1690                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1691                         (m->name == utf_init))
1692                         count++;
1693         }
1694
1695         /* Create array of constructors. */
1696
1697         oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1698
1699         if (oa == NULL)
1700                 return NULL;
1701
1702         /* Get the constructors and store them in the array. */
1703
1704         for (i = 0, index = 0; i < c->methodscount; i++) {
1705                 m = &(c->methods[i]);
1706
1707                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1708                         (m->name == utf_init)) {
1709                         // Create a java.lang.reflect.Constructor object.
1710
1711                         rc = java_lang_reflect_Constructor_create(m);
1712
1713                         /* Store object into array. */
1714
1715                         array_objectarray_element_set(oa, index, rc);
1716                         index++;
1717                 }
1718         }
1719
1720         return oa;
1721 }
1722 #endif
1723
1724
1725 /* class_get_declaredfields ****************************************************
1726
1727    Return an array of declared fields of the given class.
1728
1729    ARGUMENTS:
1730        c ............ class to get the fields of
1731            publicOnly ... show only public fields
1732
1733    RETURN:
1734        array of java.lang.reflect.Field
1735
1736 *******************************************************************************/
1737
1738 #if defined(ENABLE_JAVASE)
1739 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1740 {
1741         java_handle_objectarray_t *oa;
1742         fieldinfo                 *f;
1743         java_handle_t             *h;
1744         int                        count;
1745         int                        index;
1746         int                        i;
1747
1748         /* Determine number of fields. */
1749
1750         count = 0;
1751
1752         for (i = 0; i < c->fieldscount; i++)
1753                 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1754                         count++;
1755
1756         /* Create array of fields. */
1757
1758         oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1759
1760         if (oa == NULL)
1761                 return NULL;
1762
1763         /* Get the fields and store them in the array. */
1764
1765         for (i = 0, index = 0; i < c->fieldscount; i++) {
1766                 f = &(c->fields[i]);
1767
1768                 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1769                         // Create a java.lang.reflect.Field object.
1770
1771                         h = java_lang_reflect_Field_create(f);
1772
1773                         /* Store object into array. */
1774
1775                         array_objectarray_element_set(oa, index, h);
1776                         index++;
1777                 }
1778         }
1779
1780         return oa;
1781 }
1782 #endif
1783
1784
1785 /* class_get_declaredmethods ***************************************************
1786
1787    Return an array of declared methods of the given class.
1788
1789    ARGUMENTS:
1790        c ............ class to get the methods of
1791            publicOnly ... show only public methods
1792
1793    RETURN:
1794        array of java.lang.reflect.Method
1795
1796 *******************************************************************************/
1797
1798 #if defined(ENABLE_JAVASE)
1799 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1800 {
1801         java_handle_objectarray_t *oa;         /* result: array of Method-objects */
1802         methodinfo                *m;     /* the current method to be represented */
1803         java_handle_t             *h;
1804         int                        count;
1805         int                        index;
1806         int                        i;
1807
1808         /* JOWENN: array classes do not declare methods according to mauve
1809            test.  It should be considered, if we should return to my old
1810            clone method overriding instead of declaring it as a member
1811            function. */
1812
1813         if (class_is_array(c))
1814                 return builtin_anewarray(0, class_java_lang_reflect_Method);
1815
1816         /* Determine number of methods. */
1817
1818         count = 0;
1819
1820         for (i = 0; i < c->methodscount; i++) {
1821                 m = &(c->methods[i]);
1822
1823                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1824                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1825                         !(m->flags & ACC_MIRANDA))
1826                         count++;
1827         }
1828
1829         /* Create array of methods. */
1830
1831         oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1832
1833         if (oa == NULL)
1834                 return NULL;
1835
1836         /* Get the methods and store them in the array. */
1837
1838         for (i = 0, index = 0; i < c->methodscount; i++) {
1839                 m = &(c->methods[i]);
1840
1841                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
1842                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1843                         !(m->flags & ACC_MIRANDA)) {
1844                         // Create java.lang.reflect.Method object.
1845
1846                         h = java_lang_reflect_Method_create(m);
1847
1848                         /* Store object into array. */
1849
1850                         array_objectarray_element_set(oa, index, h);
1851                         index++;
1852                 }
1853         }
1854
1855         return oa;
1856 }
1857 #endif
1858
1859
1860 /* class_get_declaringclass ****************************************************
1861
1862    If the class or interface given is a member of another class,
1863    return the declaring class.  For array and primitive classes return
1864    NULL.
1865
1866 *******************************************************************************/
1867
1868 classinfo *class_get_declaringclass(classinfo *c)
1869 {
1870         classref_or_classinfo  cr;
1871         classinfo             *dc;
1872
1873         /* Get declaring class. */
1874
1875         cr = c->declaringclass;
1876
1877         if (cr.any == NULL)
1878                 return NULL;
1879
1880         /* Resolve the class if necessary. */
1881
1882         if (IS_CLASSREF(cr)) {
1883 /*              dc = resolve_classref_eager(cr.ref); */
1884                 dc = resolve_classref_or_classinfo_eager(cr, true);
1885
1886                 if (dc == NULL)
1887                         return NULL;
1888
1889                 /* Store the resolved class in the class structure. */
1890
1891                 cr.cls = dc;
1892         }
1893
1894         dc = cr.cls;
1895
1896         return dc;
1897 }
1898
1899
1900 /* class_get_enclosingclass ****************************************************
1901
1902    Return the enclosing class for the given class.
1903
1904 *******************************************************************************/
1905
1906 classinfo *class_get_enclosingclass(classinfo *c)
1907 {
1908         classref_or_classinfo  cr;
1909         classinfo             *ec;
1910
1911         /* Get enclosing class. */
1912
1913         cr = c->enclosingclass;
1914
1915         if (cr.any == NULL)
1916                 return NULL;
1917
1918         /* Resolve the class if necessary. */
1919
1920         if (IS_CLASSREF(cr)) {
1921 /*              ec = resolve_classref_eager(cr.ref); */
1922                 ec = resolve_classref_or_classinfo_eager(cr, true);
1923
1924                 if (ec == NULL)
1925                         return NULL;
1926
1927                 /* Store the resolved class in the class structure. */
1928
1929                 cr.cls = ec;
1930         }
1931
1932         ec = cr.cls;
1933
1934         return ec;
1935 }
1936
1937
1938 /**
1939  * Return the enclosing constructor as java.lang.reflect.Constructor
1940  * object for the given class.
1941  *
1942  * @param c class to return the enclosing constructor for
1943  *
1944  * @return java.lang.reflect.Constructor object of the enclosing
1945  * constructor
1946  */
1947 #if defined(ENABLE_JAVASE)
1948 java_handle_t* class_get_enclosingconstructor(classinfo *c)
1949 {
1950         methodinfo*    m;
1951         java_handle_t* rc;
1952
1953         m = class_get_enclosingmethod_raw(c);
1954
1955         if (m == NULL)
1956                 return NULL;
1957
1958         /* Check for <init>. */
1959
1960         if (m->name != utf_init)
1961                 return NULL;
1962
1963         // Create a java.lang.reflect.Constructor object.
1964
1965         rc = java_lang_reflect_Constructor_create(m);
1966
1967         return rc;
1968 }
1969 #endif
1970
1971
1972 /* class_get_enclosingmethod ***************************************************
1973
1974    Return the enclosing method for the given class.
1975
1976    IN:
1977        c ... class to return the enclosing method for
1978
1979    RETURN:
1980        methodinfo of the enclosing method
1981
1982 *******************************************************************************/
1983
1984 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
1985 {
1986         constant_nameandtype *cn;
1987         classinfo            *ec;
1988         methodinfo           *m;
1989
1990         /* get enclosing class and method */
1991
1992         ec = class_get_enclosingclass(c);
1993         cn = c->enclosingmethod;
1994
1995         /* check for enclosing class and method */
1996
1997         if (ec == NULL)
1998                 return NULL;
1999
2000         if (cn == NULL)
2001                 return NULL;
2002
2003         /* find method in enclosing class */
2004
2005         m = class_findmethod(ec, cn->name, cn->descriptor);
2006
2007         if (m == NULL) {
2008                 exceptions_throw_internalerror("Enclosing method doesn't exist");
2009                 return NULL;
2010         }
2011
2012         return m;
2013 }
2014
2015
2016 /**
2017  * Return the enclosing method as java.lang.reflect.Method object for
2018  * the given class.
2019  *
2020  * @param c class to return the enclosing method for
2021  *
2022  * @return java.lang.reflect.Method object of the enclosing method
2023  */
2024 #if defined(ENABLE_JAVASE)
2025 java_handle_t* class_get_enclosingmethod(classinfo *c)
2026 {
2027         methodinfo*    m;
2028         java_handle_t* rm;
2029
2030         m = class_get_enclosingmethod_raw(c);
2031
2032         if (m == NULL)
2033                 return NULL;
2034
2035         /* check for <init> */
2036
2037         if (m->name == utf_init)
2038                 return NULL;
2039
2040         // Create a java.lang.reflect.Method object.
2041
2042         rm = java_lang_reflect_Method_create(m);
2043
2044         return rm;
2045 }
2046 #endif
2047
2048
2049 /* class_get_interfaces ********************************************************
2050
2051    Return an array of interfaces of the given class.
2052
2053 *******************************************************************************/
2054
2055 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2056 {
2057         classinfo                 *ic;
2058         java_handle_objectarray_t *oa;
2059         u4                         i;
2060
2061         if (!(c->state & CLASS_LINKED))
2062                 if (!link_class(c))
2063                         return NULL;
2064
2065         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2066
2067         if (oa == NULL)
2068                 return NULL;
2069
2070         for (i = 0; i < c->interfacescount; i++) {
2071                 ic = c->interfaces[i];
2072
2073                 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2074         }
2075
2076         return oa;
2077 }
2078
2079
2080 /* class_get_annotations *******************************************************
2081
2082    Get the unparsed declared annotations in a byte array
2083    of the given class.
2084
2085    IN:
2086        c........the class of which the annotations should be returned
2087
2088    RETURN VALUE:
2089        The unparsed declared annotations in a byte array
2090        (or NULL if there aren't any).
2091
2092 *******************************************************************************/
2093
2094 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2095 {
2096 #if defined(ENABLE_ANNOTATIONS)
2097         java_handle_t *annotations; /* unparsed annotations */
2098
2099         LLNI_classinfo_field_get(c, annotations, annotations);
2100
2101         return (java_handle_bytearray_t*)annotations;
2102 #else
2103         return NULL;
2104 #endif
2105 }
2106
2107
2108 /* class_get_modifiers *********************************************************
2109
2110    Get the modifier flags of the given class.
2111
2112    IN:
2113        c....the class of which the modifier flags should be returned
2114            ignoreInnerClassesAttrib
2115    RETURN VALUE:
2116        modifier flags
2117
2118 *******************************************************************************/
2119
2120 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2121 {
2122         classref_or_classinfo  inner;
2123         classref_or_classinfo  outer;
2124         utf                   *innername;
2125         int                    i;
2126
2127         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2128                 /* search for passed class as inner class */
2129
2130                 for (i = 0; i < c->innerclasscount; i++) {
2131                         inner = c->innerclass[i].inner_class;
2132                         outer = c->innerclass[i].outer_class;
2133
2134                         /* Check if inner is a classref or a real class and get
2135                the name of the structure */
2136
2137                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2138
2139                         /* innerclass is this class */
2140
2141                         if (innername == c->name) {
2142                                 /* has the class actually an outer class? */
2143
2144                                 if (outer.any)
2145                                         /* return flags got from the outer class file */
2146                                         return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
2147                                 else
2148                                         return c->flags & ACC_CLASS_REFLECT_MASK;
2149                         }
2150                 }
2151         }
2152
2153         /* passed class is no inner class or it was not requested */
2154
2155         return c->flags & ACC_CLASS_REFLECT_MASK;
2156 }
2157
2158
2159 /* class_get_signature *********************************************************
2160
2161    Return the signature of the given class.  For array and primitive
2162    classes return NULL.
2163
2164 *******************************************************************************/
2165
2166 #if defined(ENABLE_JAVASE)
2167 utf *class_get_signature(classinfo *c)
2168 {
2169         /* For array and primitive classes return NULL. */
2170
2171         if (class_is_array(c) || class_is_primitive(c))
2172                 return NULL;
2173
2174         return c->signature;
2175 }
2176 #endif
2177
2178
2179 /* class_printflags ************************************************************
2180
2181    Prints flags of a class.
2182
2183 *******************************************************************************/
2184
2185 #if !defined(NDEBUG)
2186 void class_printflags(classinfo *c)
2187 {
2188         if (c == NULL) {
2189                 printf("NULL");
2190                 return;
2191         }
2192
2193         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
2194         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
2195         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
2196         if (c->flags & ACC_STATIC)       printf(" STATIC");
2197         if (c->flags & ACC_FINAL)        printf(" FINAL");
2198         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2199         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
2200         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
2201         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
2202         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
2203         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
2204 }
2205 #endif
2206
2207
2208 /* class_print *****************************************************************
2209
2210    Prints classname plus flags.
2211
2212 *******************************************************************************/
2213
2214 #if !defined(NDEBUG)
2215 void class_print(classinfo *c)
2216 {
2217         if (c == NULL) {
2218                 printf("NULL");
2219                 return;
2220         }
2221
2222         utf_display_printable_ascii(c->name);
2223         class_printflags(c);
2224 }
2225 #endif
2226
2227
2228 /* class_classref_print ********************************************************
2229
2230    Prints classname plus referer class.
2231
2232 *******************************************************************************/
2233
2234 #if !defined(NDEBUG)
2235 void class_classref_print(constant_classref *cr)
2236 {
2237         if (cr == NULL) {
2238                 printf("NULL");
2239                 return;
2240         }
2241
2242         utf_display_printable_ascii(cr->name);
2243         printf("(ref.by ");
2244         if (cr->referer)
2245                 class_print(cr->referer);
2246         else
2247                 printf("NULL");
2248         printf(")");
2249 }
2250 #endif
2251
2252
2253 /* class_println ***************************************************************
2254
2255    Prints classname plus flags and new line.
2256
2257 *******************************************************************************/
2258
2259 #if !defined(NDEBUG)
2260 void class_println(classinfo *c)
2261 {
2262         class_print(c);
2263         printf("\n");
2264 }
2265 #endif
2266
2267
2268 /* class_classref_println ******************************************************
2269
2270    Prints classname plus referer class and new line.
2271
2272 *******************************************************************************/
2273
2274 #if !defined(NDEBUG)
2275 void class_classref_println(constant_classref *cr)
2276 {
2277         class_classref_print(cr);
2278         printf("\n");
2279 }
2280 #endif
2281
2282
2283 /* class_classref_or_classinfo_print *******************************************
2284
2285    Prints classname plus referer class.
2286
2287 *******************************************************************************/
2288
2289 #if !defined(NDEBUG)
2290 void class_classref_or_classinfo_print(classref_or_classinfo c)
2291 {
2292         if (c.any == NULL) {
2293                 printf("(classref_or_classinfo) NULL");
2294                 return;
2295         }
2296         if (IS_CLASSREF(c))
2297                 class_classref_print(c.ref);
2298         else
2299                 class_print(c.cls);
2300 }
2301 #endif
2302
2303
2304 /* class_classref_or_classinfo_println *****************************************
2305
2306    Prints classname plus referer class and a newline.
2307
2308 *******************************************************************************/
2309
2310 #if !defined(NDEBUG)
2311 void class_classref_or_classinfo_println(classref_or_classinfo c)
2312 {
2313         class_classref_or_classinfo_print(c);
2314         printf("\n");
2315 }
2316 #endif
2317
2318
2319 /* class_showconstantpool ******************************************************
2320
2321    Dump the constant pool of the given class to stdout.
2322
2323 *******************************************************************************/
2324
2325 #if !defined(NDEBUG)
2326 void class_showconstantpool (classinfo *c) 
2327 {
2328         u4 i;
2329         void* e;
2330
2331         printf ("---- dump of constant pool ----\n");
2332
2333         for (i=0; i<c->cpcount; i++) {
2334                 printf ("#%d:  ", (int) i);
2335                 
2336                 e = c -> cpinfos [i];
2337                 if (e) {
2338                         
2339                         switch (c -> cptags [i]) {
2340                         case CONSTANT_Class:
2341                                 printf ("Classreference -> ");
2342                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2343                                 break;
2344                         case CONSTANT_Fieldref:
2345                                 printf ("Fieldref -> ");
2346                                 field_fieldref_print((constant_FMIref *) e);
2347                                 break;
2348                         case CONSTANT_Methodref:
2349                                 printf ("Methodref -> ");
2350                                 method_methodref_print((constant_FMIref *) e);
2351                                 break;
2352                         case CONSTANT_InterfaceMethodref:
2353                                 printf ("InterfaceMethod -> ");
2354                                 method_methodref_print((constant_FMIref *) e);
2355                                 break;
2356                         case CONSTANT_String:
2357                                 printf ("String -> ");
2358                                 utf_display_printable_ascii (e);
2359                                 break;
2360                         case CONSTANT_Integer:
2361                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2362                                 break;
2363                         case CONSTANT_Float:
2364                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2365                                 break;
2366                         case CONSTANT_Double:
2367                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2368                                 break;
2369                         case CONSTANT_Long:
2370                                 {
2371                                         u8 v = ((constant_long*)e) -> value;
2372 #if U8_AVAILABLE
2373                                         printf ("Long -> %ld", (long int) v);
2374 #else
2375                                         printf ("Long -> HI: %ld, LO: %ld\n", 
2376                                                         (long int) v.high, (long int) v.low);
2377 #endif 
2378                                 }
2379                                 break;
2380                         case CONSTANT_NameAndType:
2381                                 {
2382                                         constant_nameandtype *cnt = e;
2383                                         printf ("NameAndType: ");
2384                                         utf_display_printable_ascii (cnt->name);
2385                                         printf (" ");
2386                                         utf_display_printable_ascii (cnt->descriptor);
2387                                 }
2388                                 break;
2389                         case CONSTANT_Utf8:
2390                                 printf ("Utf8 -> ");
2391                                 utf_display_printable_ascii (e);
2392                                 break;
2393                         default: 
2394                                 log_text("Invalid type of ConstantPool-Entry");
2395                                 assert(0);
2396                         }
2397                 }
2398
2399                 printf ("\n");
2400         }
2401 }
2402 #endif /* !defined(NDEBUG) */
2403
2404
2405 /* class_showmethods ***********************************************************
2406
2407    Dump info about the fields and methods of the given class to stdout.
2408
2409 *******************************************************************************/
2410
2411 #if !defined(NDEBUG)
2412 void class_showmethods (classinfo *c)
2413 {
2414         s4 i;
2415         
2416         printf("--------- Fields and Methods ----------------\n");
2417         printf("Flags: ");
2418         class_printflags(c);
2419         printf("\n");
2420
2421         printf("This: ");
2422         utf_display_printable_ascii(c->name);
2423         printf("\n");
2424
2425         if (c->super) {
2426                 printf("Super: ");
2427                 utf_display_printable_ascii(c->super->name);
2428                 printf ("\n");
2429         }
2430
2431         printf("Index: %d\n", c->index);
2432         
2433         printf("Interfaces:\n");        
2434         for (i = 0; i < c->interfacescount; i++) {
2435                 printf("   ");
2436                 utf_display_printable_ascii(c->interfaces[i]->name);
2437                 printf (" (%d)\n", c->interfaces[i]->index);
2438         }
2439
2440         printf("Fields:\n");
2441         for (i = 0; i < c->fieldscount; i++)
2442                 field_println(&(c->fields[i]));
2443
2444         printf("Methods:\n");
2445         for (i = 0; i < c->methodscount; i++) {
2446                 methodinfo *m = &(c->methods[i]);
2447
2448                 if (!(m->flags & ACC_STATIC))
2449                         printf("vftblindex: %d   ", m->vftblindex);
2450
2451                 method_println(m);
2452         }
2453
2454         printf ("Virtual function table:\n");
2455         for (i = 0; i < c->vftbl->vftbllength; i++)
2456                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
2457 }
2458 #endif /* !defined(NDEBUG) */
2459
2460
2461 /*
2462  * These are local overrides for various environment variables in Emacs.
2463  * Please do not remove this and leave it at the end of the file, where
2464  * Emacs will automagically detect them.
2465  * ---------------------------------------------------------------------
2466  * Local variables:
2467  * mode: c
2468  * indent-tabs-mode: t
2469  * c-basic-offset: 4
2470  * tab-width: 4
2471  * End:
2472  * vim:noexpandtab:sw=4:ts=4:
2473  */