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