* src/vm/class.hpp (class_is_arraycompatible): New method (moved from builtin).
[cacao.git] / src / vm / class.cpp
1 /* src/vm/class.cpp - 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.hpp"
38
39 #include "native/llni.h"
40
41 #include "threads/lock.hpp"
42 #include "threads/mutex.hpp"
43
44 #include "toolbox/logging.hpp"
45
46 #include "vm/array.hpp"
47 #include "vm/jit/builtin.hpp"
48 #include "vm/class.hpp"
49 #include "vm/classcache.hpp"
50 #include "vm/exceptions.hpp"
51 #include "vm/global.h"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/linker.hpp"
55 #include "vm/loader.hpp"
56 #include "vm/options.h"
57 #include "vm/resolve.hpp"
58
59 #if defined(ENABLE_STATISTICS)
60 # include "vm/statistics.h"
61 #endif
62
63 #include "vm/suck.hpp"
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         c->object.header.lockword.init();
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 = (utf*) 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 = (constant_classref*) innerclass_getconstant(c, class_index, CONSTANT_Class);
426
427         /* get method index */
428
429         method_index = suck_u2(cb);
430         cn = (constant_nameandtype*) 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                         (utf*) 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 = (constant_classref*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
525                                 outer.ref = (constant_classref*) innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
526                                 name      = (utf*) 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
823         cl = component->classloader;
824
825     /* Assemble the array class name */
826     namelen = component->name->blength;
827     
828     if (component->name->text[0] == '[') {
829         /* the component is itself an array */
830         namebuf = MNEW(char, namelen + 1);
831         namebuf[0] = '[';
832         MCOPY(namebuf + 1, component->name->text, char, namelen);
833         namelen++;
834     }
835         else {
836         /* the component is a non-array class */
837         namebuf = MNEW(char, namelen + 3);
838         namebuf[0] = '[';
839         namebuf[1] = 'L';
840         MCOPY(namebuf + 2, component->name->text, char, namelen);
841         namebuf[2 + namelen] = ';';
842         namelen += 3;
843     }
844
845         u = utf_new(namebuf, namelen);
846
847         MFREE(namebuf, char, namelen);
848
849         c = get_array_class(u, cl, cl, link);
850
851         return c;
852 }
853
854
855 /* class_multiarray_of *********************************************************
856
857    Returns an array class with the given dimension and element class.
858    The array class is dynamically created if neccessary.
859
860 *******************************************************************************/
861
862 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
863 {
864     s4 namelen;
865     char *namebuf;
866         classinfo *c;
867
868         if (dim < 1) {
869                 log_text("Invalid array dimension requested");
870                 assert(0);
871         }
872
873     /* Assemble the array class name */
874     namelen = element->name->blength;
875     
876     if (element->name->text[0] == '[') {
877         /* the element is itself an array */
878         namebuf = MNEW(char, namelen + dim);
879         memcpy(namebuf + dim, element->name->text, namelen);
880         namelen += dim;
881     }
882     else {
883         /* the element is a non-array class */
884         namebuf = MNEW(char, namelen + 2 + dim);
885         namebuf[dim] = 'L';
886         memcpy(namebuf + dim + 1, element->name->text, namelen);
887         namelen += (2 + dim);
888         namebuf[namelen - 1] = ';';
889     }
890         memset(namebuf, '[', dim);
891
892         utf* u = utf_new(namebuf, namelen);
893
894         MFREE(namebuf, char, namelen);
895
896         c = get_array_class(u,
897                                                 element->classloader,
898                                                 element->classloader,
899                                                 link);
900
901         return c;
902 }
903
904
905 /* class_lookup_classref *******************************************************
906
907    Looks up the constant_classref for a given classname in the classref
908    tables of a class.
909
910    IN:
911        cls..............the class containing the reference
912            name.............the name of the class refered to
913
914     RETURN VALUE:
915            a pointer to a constant_classref, or 
916            NULL if the reference was not found
917    
918 *******************************************************************************/
919
920 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
921 {
922         constant_classref *ref;
923         extra_classref *xref;
924         int count;
925
926         assert(cls);
927         assert(name);
928         assert(!cls->classrefcount || cls->classrefs);
929         
930         /* first search the main classref table */
931         count = cls->classrefcount;
932         ref = cls->classrefs;
933         for (; count; --count, ++ref)
934                 if (ref->name == name)
935                         return ref;
936
937         /* next try the list of extra classrefs */
938         for (xref = cls->extclassrefs; xref; xref = xref->next) {
939                 if (xref->classref.name == name)
940                         return &(xref->classref);
941         }
942
943         /* not found */
944         return NULL;
945 }
946
947
948 /* class_get_classref **********************************************************
949
950    Returns the constant_classref for a given classname.
951
952    IN:
953        cls..............the class containing the reference
954            name.............the name of the class refered to
955
956    RETURN VALUE:
957        a pointer to a constant_classref (never NULL)
958
959    NOTE:
960        The given name is not checked for validity!
961    
962 *******************************************************************************/
963
964 constant_classref *class_get_classref(classinfo *cls, utf *name)
965 {
966         constant_classref *ref;
967         extra_classref *xref;
968
969         assert(cls);
970         assert(name);
971
972         ref = class_lookup_classref(cls,name);
973         if (ref)
974                 return ref;
975
976         xref = NEW(extra_classref);
977         CLASSREF_INIT(xref->classref,cls,name);
978
979         xref->next = cls->extclassrefs;
980         cls->extclassrefs = xref;
981
982         return &(xref->classref);
983 }
984
985
986 /* class_get_self_classref *****************************************************
987
988    Returns the constant_classref to the class itself.
989
990    IN:
991        cls..............the class containing the reference
992
993    RETURN VALUE:
994        a pointer to a constant_classref (never NULL)
995
996 *******************************************************************************/
997
998 constant_classref *class_get_self_classref(classinfo *cls)
999 {
1000         /* XXX this should be done in a faster way. Maybe always make */
1001         /* the classref of index 0 a self reference.                  */
1002         return class_get_classref(cls,cls->name);
1003 }
1004
1005 /* class_get_classref_multiarray_of ********************************************
1006
1007    Returns an array type reference with the given dimension and element class
1008    reference.
1009
1010    IN:
1011        dim..............the requested dimension
1012                             dim must be in [1;255]. This is NOT checked!
1013            ref..............the component class reference
1014
1015    RETURN VALUE:
1016        a pointer to the class reference for the array type
1017
1018    NOTE:
1019        The referer of `ref` is used as the referer for the new classref.
1020
1021 *******************************************************************************/
1022
1023 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
1024 {
1025     s4 namelen;
1026     char *namebuf;
1027         constant_classref *cr;
1028
1029         assert(ref);
1030         assert(dim >= 1 && dim <= 255);
1031
1032     /* Assemble the array class name */
1033     namelen = ref->name->blength;
1034     
1035     if (ref->name->text[0] == '[') {
1036         /* the element is itself an array */
1037         namebuf = MNEW(char, namelen + dim);
1038         memcpy(namebuf + dim, ref->name->text, namelen);
1039         namelen += dim;
1040     }
1041     else {
1042         /* the element is a non-array class */
1043         namebuf = MNEW(char, namelen + 2 + dim);
1044         namebuf[dim] = 'L';
1045         memcpy(namebuf + dim + 1, ref->name->text, namelen);
1046         namelen += (2 + dim);
1047         namebuf[namelen - 1] = ';';
1048     }
1049         memset(namebuf, '[', dim);
1050
1051         utf* u = utf_new(namebuf, namelen);
1052
1053         MFREE(namebuf, char, namelen);
1054
1055     cr = class_get_classref(ref->referer, u);
1056
1057         return cr;
1058 }
1059
1060
1061 /* class_get_classref_component_of *********************************************
1062
1063    Returns the component classref of a given array type reference
1064
1065    IN:
1066        ref..............the array type reference
1067
1068    RETURN VALUE:
1069        a reference to the component class, or
1070            NULL if `ref` is not an object array type reference
1071
1072    NOTE:
1073        The referer of `ref` is used as the referer for the new classref.
1074
1075 *******************************************************************************/
1076
1077 constant_classref *class_get_classref_component_of(constant_classref *ref)
1078 {
1079         s4 namelen;
1080         char *name;
1081         
1082         assert(ref);
1083
1084         name = ref->name->text;
1085         if (*name++ != '[')
1086                 return NULL;
1087         
1088         namelen = ref->name->blength - 1;
1089         if (*name == 'L') {
1090                 name++;
1091                 namelen -= 2;
1092         }
1093         else if (*name != '[') {
1094                 return NULL;
1095         }
1096
1097     return class_get_classref(ref->referer, utf_new(name, namelen));
1098 }
1099
1100
1101 /* class_findmethod ************************************************************
1102         
1103    Searches a 'classinfo' structure for a method having the given name
1104    and descriptor. If descriptor is NULL, it is ignored.
1105
1106 *******************************************************************************/
1107
1108 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
1109 {
1110         methodinfo *m;
1111         s4          i;
1112
1113         for (i = 0; i < c->methodscount; i++) {
1114                 m = &(c->methods[i]);
1115
1116                 if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
1117                         return m;
1118         }
1119
1120         return NULL;
1121 }
1122
1123
1124 /* class_resolvemethod *********************************************************
1125         
1126    Searches a class and it's super classes for a method.
1127
1128    Superinterfaces are *not* searched.
1129
1130 *******************************************************************************/
1131
1132 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
1133 {
1134         methodinfo *m;
1135
1136         while (c) {
1137                 m = class_findmethod(c, name, desc);
1138
1139                 if (m)
1140                         return m;
1141
1142                 /* JVM Specification bug: 
1143
1144                    It is important NOT to resolve special <init> and <clinit>
1145                    methods to super classes or interfaces; yet, this is not
1146                    explicited in the specification.  Section 5.4.3.3 should be
1147                    updated appropriately.  */
1148
1149                 if (name == utf_init || name == utf_clinit)
1150                         return NULL;
1151
1152                 c = c->super;
1153         }
1154
1155         return NULL;
1156 }
1157
1158
1159 /* class_resolveinterfacemethod_intern *****************************************
1160
1161    Internally used helper function. Do not use this directly.
1162
1163 *******************************************************************************/
1164
1165 static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
1166                                                                                                            utf *name, utf *desc)
1167 {
1168         methodinfo *m;
1169         s4          i;
1170
1171         /* try to find the method in the class */
1172
1173         m = class_findmethod(c, name, desc);
1174
1175         if (m != NULL)
1176                 return m;
1177
1178         /* No method found?  Try the super interfaces. */
1179
1180         for (i = 0; i < c->interfacescount; i++) {
1181                 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1182
1183                 if (m != NULL)
1184                         return m;
1185         }
1186
1187         /* no method found */
1188
1189         return NULL;
1190 }
1191
1192
1193 /* class_resolveclassmethod ****************************************************
1194         
1195    Resolves a reference from REFERER to a method with NAME and DESC in
1196    class C.
1197
1198    If the method cannot be resolved the return value is NULL. If
1199    EXCEPT is true *exceptionptr is set, too.
1200
1201 *******************************************************************************/
1202
1203 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
1204                                                                          classinfo *referer, bool throwexception)
1205 {
1206         classinfo  *cls;
1207         methodinfo *m;
1208         s4          i;
1209
1210 /*      if (c->flags & ACC_INTERFACE) { */
1211 /*              if (throwexception) */
1212 /*                      *exceptionptr = */
1213 /*                              new_exception(string_java_lang_IncompatibleClassChangeError); */
1214 /*              return NULL; */
1215 /*      } */
1216
1217         /* try class c and its superclasses */
1218
1219         cls = c;
1220
1221         m = class_resolvemethod(cls, name, desc);
1222
1223         if (m != NULL)
1224                 goto found;
1225
1226         /* Try the super interfaces. */
1227
1228         for (i = 0; i < c->interfacescount; i++) {
1229                 m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
1230
1231                 if (m != NULL)
1232                         goto found;
1233         }
1234         
1235         if (throwexception)
1236                 exceptions_throw_nosuchmethoderror(c, name, desc);
1237
1238         return NULL;
1239
1240  found:
1241         if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
1242                 if (throwexception)
1243                         exceptions_throw_abstractmethoderror();
1244
1245                 return NULL;
1246         }
1247
1248         /* XXX check access rights */
1249
1250         return m;
1251 }
1252
1253
1254 /* class_resolveinterfacemethod ************************************************
1255
1256    Resolves a reference from REFERER to a method with NAME and DESC in
1257    interface C.
1258
1259    If the method cannot be resolved the return value is NULL. If
1260    EXCEPT is true *exceptionptr is set, too.
1261
1262 *******************************************************************************/
1263
1264 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
1265                                                                                  classinfo *referer, bool throwexception)
1266 {
1267         methodinfo *mi;
1268
1269         if (!(c->flags & ACC_INTERFACE)) {
1270                 if (throwexception)
1271                         exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
1272
1273                 return NULL;
1274         }
1275
1276         mi = class_resolveinterfacemethod_intern(c, name, desc);
1277
1278         if (mi != NULL)
1279                 return mi;
1280
1281         /* try class java.lang.Object */
1282
1283         mi = class_findmethod(class_java_lang_Object, name, desc);
1284
1285         if (mi != NULL)
1286                 return mi;
1287
1288         if (throwexception)
1289                 exceptions_throw_nosuchmethoderror(c, name, desc);
1290
1291         return NULL;
1292 }
1293
1294
1295 /* class_findfield *************************************************************
1296         
1297    Searches for field with specified name and type in a classinfo
1298    structure. If no such field is found NULL is returned.
1299
1300 *******************************************************************************/
1301
1302 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
1303 {
1304         s4 i;
1305
1306         for (i = 0; i < c->fieldscount; i++)
1307                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1308                         return &(c->fields[i]);
1309
1310         if (c->super != NULL)
1311                 return class_findfield(c->super, name, desc);
1312
1313         return NULL;
1314 }
1315
1316
1317 /* class_findfield_approx ******************************************************
1318         
1319    Searches in 'classinfo'-structure for a field with the specified
1320    name.
1321
1322 *******************************************************************************/
1323  
1324 fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
1325 {
1326         for (int32_t i = 0; i < c->fieldscount; i++) {
1327                 fieldinfo* f = &(c->fields[i]);
1328
1329                 if (f->name == name)
1330                         return f;
1331         }
1332
1333         // Field not found.
1334         exceptions_throw_nosuchfielderror(c, name);
1335         return NULL;
1336 }
1337
1338
1339 /****************** Function: class_resolvefield_int ***************************
1340
1341     This is an internally used helper function. Do not use this directly.
1342
1343         Tries to resolve a field having the given name and type.
1344     If the field cannot be resolved, NULL is returned.
1345
1346 *******************************************************************************/
1347
1348 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
1349 {
1350         fieldinfo *fi;
1351         s4         i;
1352
1353         /* search for field in class c */
1354
1355         for (i = 0; i < c->fieldscount; i++) { 
1356                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
1357                         return &(c->fields[i]);
1358                 }
1359     }
1360
1361         /* Try super interfaces recursively. */
1362
1363         for (i = 0; i < c->interfacescount; i++) {
1364                 fi = class_resolvefield_int(c->interfaces[i], name, desc);
1365
1366                 if (fi != NULL)
1367                         return fi;
1368         }
1369
1370         /* Try super class. */
1371
1372         if (c->super != NULL)
1373                 return class_resolvefield_int(c->super, name, desc);
1374
1375         /* not found */
1376
1377         return NULL;
1378 }
1379
1380
1381 /********************* Function: class_resolvefield ***************************
1382         
1383         Resolves a reference from REFERER to a field with NAME and DESC in class C.
1384
1385     If the field cannot be resolved, an exception is thrown and the
1386     return value is NULL.
1387
1388 *******************************************************************************/
1389
1390 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
1391 {
1392         fieldinfo *fi;
1393
1394         fi = class_resolvefield_int(c, name, desc);
1395
1396         if (!fi) {
1397                 exceptions_throw_nosuchfielderror(c, name);
1398                 return NULL;
1399         }
1400
1401         /* XXX check access rights */
1402
1403         return fi;
1404 }
1405
1406
1407 /* class_issubclass ************************************************************
1408
1409    Checks if sub is a descendant of super.
1410         
1411 *******************************************************************************/
1412
1413 bool class_issubclass(classinfo *sub, classinfo *super)
1414 {
1415         classinfo *c;
1416
1417         c = sub;
1418
1419         for (;;) {
1420                 /* We reached java/lang/Object and did not find the requested
1421                    super class. */
1422
1423                 if (c == NULL)
1424                         return false;
1425
1426                 /* We found the requested super class. */
1427
1428                 if (c == super)
1429                         return true;
1430
1431                 c = c->super;
1432         }
1433 }
1434
1435
1436 /* class_isanysubclass *********************************************************
1437
1438    Checks a subclass relation between two classes. Implemented
1439    interfaces are interpreted as super classes.
1440
1441    Return value: 1 ... sub is subclass of super
1442                  0 ... otherwise
1443
1444 *******************************************************************************/
1445
1446 bool class_isanysubclass(classinfo *sub, classinfo *super)
1447 {
1448         bool result;
1449
1450         /* This is the trivial case. */
1451
1452         if (sub == super)
1453                 return true;
1454
1455         /* Primitive classes are only subclasses of themselves. */
1456
1457         if (class_is_primitive(sub) || class_is_primitive(super))
1458                 return false;
1459
1460         /* Check for interfaces. */
1461
1462         if (super->flags & ACC_INTERFACE) {
1463                 result = (sub->vftbl->interfacetablelength > super->index) &&
1464                         (sub->vftbl->interfacetable[-super->index] != NULL);
1465         }
1466         else {
1467                 /* java.lang.Object is the only super class of any
1468                    interface. */
1469
1470                 if (sub->flags & ACC_INTERFACE)
1471                         return (super == class_java_lang_Object);
1472
1473 #if USES_NEW_SUBTYPE
1474                 result = fast_subtype_check(sub->vftbl, super->vftbl);
1475 #else
1476                 LOCK_CLASSRENUMBER_LOCK;
1477
1478                 uint32_t diffval = sub->vftbl->baseval - super->vftbl->baseval;
1479                 result = diffval <= (uint32_t) super->vftbl->diffval;
1480
1481                 UNLOCK_CLASSRENUMBER_LOCK;
1482 #endif
1483         }
1484
1485         return result;
1486 }
1487
1488
1489 /* class_is_arraycompatible ****************************************************
1490
1491    Checks if two array type descriptors are assignment compatible.
1492
1493    RETURN VALUE:
1494       true .... target = desc is possible
1495       false ... otherwise
1496                         
1497 *******************************************************************************/
1498
1499 bool class_is_arraycompatible(arraydescriptor *desc, arraydescriptor *target)
1500 {
1501         if (desc == target)
1502                 return 1;
1503
1504         if (desc->arraytype != target->arraytype)
1505                 return 0;
1506
1507         if (desc->arraytype != ARRAYTYPE_OBJECT)
1508                 return 1;
1509         
1510         /* {both arrays are arrays of references} */
1511
1512         if (desc->dimension == target->dimension) {
1513                 if (!desc->elementvftbl)
1514                         return 0;
1515                 /* an array which contains elements of interface types is
1516            allowed to be casted to Object (JOWENN)*/
1517
1518                 if ((desc->elementvftbl->baseval < 0) &&
1519                         (target->elementvftbl->baseval == 1))
1520                         return 1;
1521
1522                 return class_isanysubclass(desc->elementvftbl->clazz,
1523                                                                    target->elementvftbl->clazz);
1524         }
1525
1526         if (desc->dimension < target->dimension)
1527                 return 0;
1528
1529         /* {desc has higher dimension than target} */
1530
1531         return class_isanysubclass(pseudo_class_Arraystub,
1532                                                            target->elementvftbl->clazz);
1533 }
1534
1535
1536 /* class_is_assignable_from ****************************************************
1537
1538    Return whether an instance of the "from" class parameter would be
1539    an instance of this class "to" as well.
1540
1541    ARGUMENTS:
1542        to ..... class
1543            from ... class
1544
1545    RETURN:
1546        true .... is assignable
1547            false ... is not assignable
1548
1549 *******************************************************************************/
1550
1551 bool class_is_assignable_from(classinfo *to, classinfo *from)
1552 {
1553         if (!(to->state & CLASS_LINKED))
1554                 if (!link_class(to))
1555                         return false;
1556
1557         if (!(from->state & CLASS_LINKED))
1558                 if (!link_class(from))
1559                         return false;
1560
1561         /* Decide whether we are dealing with array types or object types. */
1562
1563         if (class_is_array(to))
1564                 return class_is_arraycompatible(from->vftbl->arraydesc, to->vftbl->arraydesc);
1565         else
1566                 return class_isanysubclass(from, to);
1567 }
1568
1569
1570 /* class_is_instance ***********************************************************
1571
1572    Return if the given Java object is an instance of the given class.
1573
1574    ARGUMENTS:
1575        c ... class
1576            h ... Java object
1577
1578    RETURN:
1579        true .... is instance
1580            false ... is not instance
1581
1582 *******************************************************************************/
1583
1584 bool class_is_instance(classinfo *c, java_handle_t *h)
1585 {
1586         if (!(c->state & CLASS_LINKED))
1587                 if (!link_class(c))
1588                         return false;
1589
1590         /* Decide whether we are dealing with array types or object types. */
1591
1592         if (class_is_array(c))
1593                 return builtin_arrayinstanceof(h, c);
1594         else
1595                 return builtin_instanceof(h, c);
1596 }
1597
1598
1599 /* class_get_componenttype *****************************************************
1600
1601    Return the component class of the given class.  If the given class
1602    is not an array, return NULL.
1603
1604 *******************************************************************************/
1605
1606 classinfo *class_get_componenttype(classinfo *c)
1607 {
1608         classinfo       *component;
1609         arraydescriptor *ad;
1610         
1611         /* XXX maybe we could find a way to do this without linking. */
1612         /* This way should be safe and easy, however.                */
1613
1614         if (!(c->state & CLASS_LINKED))
1615                 if (!link_class(c))
1616                         return NULL;
1617
1618         ad = c->vftbl->arraydesc;
1619         
1620         if (ad == NULL)
1621                 return NULL;
1622         
1623         if (ad->arraytype == ARRAYTYPE_OBJECT)
1624                 component = ad->componentvftbl->clazz;
1625         else
1626                 component = Primitive::get_class_by_type(ad->arraytype);
1627                 
1628         return component;
1629 }
1630
1631
1632 /* class_get_declaredclasses ***************************************************
1633
1634    Return an array of declared classes of the given class.
1635
1636 *******************************************************************************/
1637
1638 java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
1639 {
1640         classref_or_classinfo  inner;
1641         classref_or_classinfo  outer;
1642         utf                   *outername;
1643         int                    declaredclasscount;  /* number of declared classes */
1644         int                    pos;                     /* current declared class */
1645         java_handle_objectarray_t *oa;               /* array of declared classes */
1646         int                    i;
1647         classinfo             *ic;
1648
1649         declaredclasscount = 0;
1650
1651         if (!class_is_primitive(c) && !class_is_array(c)) {
1652                 /* Determine number of declared classes. */
1653
1654                 for (i = 0; i < c->innerclasscount; i++) {
1655                         /* Get outer-class.  If the inner-class is not a member
1656                            class, the outer-class is NULL. */
1657
1658                         outer = c->innerclass[i].outer_class;
1659
1660                         if (outer.any == NULL)
1661                                 continue;
1662
1663                         /* Check if outer-class is a classref or a real class and
1664                get the class name from the structure. */
1665
1666                         outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1667
1668                         /* Outer class is this class. */
1669
1670                         if ((outername == c->name) &&
1671                                 ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
1672                                 declaredclasscount++;
1673                 }
1674         }
1675
1676         /* Allocate Class[] and check for OOM. */
1677
1678         oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
1679
1680         if (oa == NULL)
1681                 return NULL;
1682
1683         for (i = 0, pos = 0; i < c->innerclasscount; i++) {
1684                 inner = c->innerclass[i].inner_class;
1685                 outer = c->innerclass[i].outer_class;
1686
1687                 /* Get outer-class.  If the inner-class is not a member class,
1688                    the outer-class is NULL. */
1689
1690                 if (outer.any == NULL)
1691                         continue;
1692
1693                 /* Check if outer_class is a classref or a real class and get
1694                    the class name from the structure. */
1695
1696                 outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
1697
1698                 /* Outer class is this class. */
1699
1700                 if ((outername == c->name) &&
1701                         ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
1702
1703                         ic = resolve_classref_or_classinfo_eager(inner, false);
1704
1705                         if (ic == NULL)
1706                                 return NULL;
1707
1708                         if (!(ic->state & CLASS_LINKED))
1709                                 if (!link_class(ic))
1710                                         return NULL;
1711
1712                         LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
1713                 }
1714         }
1715
1716         return oa;
1717 }
1718
1719
1720 /**
1721  * Return an array of declared constructors of the given class.
1722  *
1723  * @param c          class to get the constructors of
1724  * @param publicOnly show only public fields
1725  *
1726  * @return array of java.lang.reflect.Constructor
1727  */
1728 #if defined(ENABLE_JAVASE)
1729 java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
1730 {
1731         methodinfo*                m;
1732         java_handle_objectarray_t* oa;
1733         int                        count;
1734         int                        index;
1735         int                        i;
1736
1737         /* Determine number of constructors. */
1738
1739         count = 0;
1740
1741         for (i = 0; i < c->methodscount; i++) {
1742                 m = &(c->methods[i]);
1743
1744                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1745                         (m->name == utf_init))
1746                         count++;
1747         }
1748
1749         /* Create array of constructors. */
1750
1751         oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
1752
1753         if (oa == NULL)
1754                 return NULL;
1755
1756         /* Get the constructors and store them in the array. */
1757
1758         for (i = 0, index = 0; i < c->methodscount; i++) {
1759                 m = &(c->methods[i]);
1760
1761                 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
1762                         (m->name == utf_init)) {
1763                         // Create a java.lang.reflect.Constructor object.
1764
1765                         java_lang_reflect_Constructor rc(m);
1766
1767                         /* Store object into array. */
1768
1769                         array_objectarray_element_set(oa, index, rc.get_handle());
1770                         index++;
1771                 }
1772         }
1773
1774         return oa;
1775 }
1776 #endif
1777
1778
1779 /* class_get_declaredfields ****************************************************
1780
1781    Return an array of declared fields of the given class.
1782
1783    ARGUMENTS:
1784        c ............ class to get the fields of
1785            publicOnly ... show only public fields
1786
1787    RETURN:
1788        array of java.lang.reflect.Field
1789
1790 *******************************************************************************/
1791
1792 #if defined(ENABLE_JAVASE)
1793 java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
1794 {
1795         java_handle_objectarray_t *oa;
1796         fieldinfo                 *f;
1797         int                        count;
1798         int                        index;
1799         int                        i;
1800
1801         /* Determine number of fields. */
1802
1803         count = 0;
1804
1805         for (i = 0; i < c->fieldscount; i++)
1806                 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
1807                         count++;
1808
1809         /* Create array of fields. */
1810
1811         oa = builtin_anewarray(count, class_java_lang_reflect_Field);
1812
1813         if (oa == NULL)
1814                 return NULL;
1815
1816         /* Get the fields and store them in the array. */
1817
1818         for (i = 0, index = 0; i < c->fieldscount; i++) {
1819                 f = &(c->fields[i]);
1820
1821                 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
1822                         // Create a java.lang.reflect.Field object.
1823
1824                         java_lang_reflect_Field rf(f);
1825
1826                         /* Store object into array. */
1827
1828                         array_objectarray_element_set(oa, index, rf.get_handle());
1829                         index++;
1830                 }
1831         }
1832
1833         return oa;
1834 }
1835 #endif
1836
1837
1838 /* class_get_declaredmethods ***************************************************
1839
1840    Return an array of declared methods of the given class.
1841
1842    ARGUMENTS:
1843        c ............ class to get the methods of
1844            publicOnly ... show only public methods
1845
1846    RETURN:
1847        array of java.lang.reflect.Method
1848
1849 *******************************************************************************/
1850
1851 #if defined(ENABLE_JAVASE)
1852 java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
1853 {
1854         java_handle_objectarray_t *oa;         /* result: array of Method-objects */
1855         methodinfo                *m;     /* the current method to be represented */
1856         int                        count;
1857         int                        index;
1858         int                        i;
1859
1860         /* JOWENN: array classes do not declare methods according to mauve
1861            test.  It should be considered, if we should return to my old
1862            clone method overriding instead of declaring it as a member
1863            function. */
1864
1865         if (class_is_array(c))
1866                 return builtin_anewarray(0, class_java_lang_reflect_Method);
1867
1868         /* Determine number of methods. */
1869
1870         count = 0;
1871
1872         for (i = 0; i < c->methodscount; i++) {
1873                 m = &(c->methods[i]);
1874
1875                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
1876                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1877                         !(m->flags & ACC_MIRANDA))
1878                         count++;
1879         }
1880
1881         /* Create array of methods. */
1882
1883         oa = builtin_anewarray(count, class_java_lang_reflect_Method);
1884
1885         if (oa == NULL)
1886                 return NULL;
1887
1888         /* Get the methods and store them in the array. */
1889
1890         for (i = 0, index = 0; i < c->methodscount; i++) {
1891                 m = &(c->methods[i]);
1892
1893                 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
1894                         ((m->name != utf_init) && (m->name != utf_clinit)) &&
1895                         !(m->flags & ACC_MIRANDA)) {
1896                         // Create java.lang.reflect.Method object.
1897
1898                         java_lang_reflect_Method rm(m);
1899
1900                         /* Store object into array. */
1901
1902                         array_objectarray_element_set(oa, index, rm.get_handle());
1903                         index++;
1904                 }
1905         }
1906
1907         return oa;
1908 }
1909 #endif
1910
1911
1912 /* class_get_declaringclass ****************************************************
1913
1914    If the class or interface given is a member of another class,
1915    return the declaring class.  For array and primitive classes return
1916    NULL.
1917
1918 *******************************************************************************/
1919
1920 classinfo *class_get_declaringclass(classinfo *c)
1921 {
1922         classref_or_classinfo  cr;
1923         classinfo             *dc;
1924
1925         /* Get declaring class. */
1926
1927         cr = c->declaringclass;
1928
1929         if (cr.any == NULL)
1930                 return NULL;
1931
1932         /* Resolve the class if necessary. */
1933
1934         if (IS_CLASSREF(cr)) {
1935 /*              dc = resolve_classref_eager(cr.ref); */
1936                 dc = resolve_classref_or_classinfo_eager(cr, true);
1937
1938                 if (dc == NULL)
1939                         return NULL;
1940
1941                 /* Store the resolved class in the class structure. */
1942
1943                 cr.cls = dc;
1944         }
1945
1946         dc = cr.cls;
1947
1948         return dc;
1949 }
1950
1951
1952 /* class_get_enclosingclass ****************************************************
1953
1954    Return the enclosing class for the given class.
1955
1956 *******************************************************************************/
1957
1958 classinfo *class_get_enclosingclass(classinfo *c)
1959 {
1960         classref_or_classinfo  cr;
1961         classinfo             *ec;
1962
1963         /* Get enclosing class. */
1964
1965         cr = c->enclosingclass;
1966
1967         if (cr.any == NULL)
1968                 return NULL;
1969
1970         /* Resolve the class if necessary. */
1971
1972         if (IS_CLASSREF(cr)) {
1973 /*              ec = resolve_classref_eager(cr.ref); */
1974                 ec = resolve_classref_or_classinfo_eager(cr, true);
1975
1976                 if (ec == NULL)
1977                         return NULL;
1978
1979                 /* Store the resolved class in the class structure. */
1980
1981                 cr.cls = ec;
1982         }
1983
1984         ec = cr.cls;
1985
1986         return ec;
1987 }
1988
1989
1990 /**
1991  * Return the enclosing constructor as java.lang.reflect.Constructor
1992  * object for the given class.
1993  *
1994  * @param c class to return the enclosing constructor for
1995  *
1996  * @return java.lang.reflect.Constructor object of the enclosing
1997  * constructor
1998  */
1999 #if defined(ENABLE_JAVASE)
2000 java_handle_t* class_get_enclosingconstructor(classinfo *c)
2001 {
2002         methodinfo*    m;
2003
2004         m = class_get_enclosingmethod_raw(c);
2005
2006         if (m == NULL)
2007                 return NULL;
2008
2009         /* Check for <init>. */
2010
2011         if (m->name != utf_init)
2012                 return NULL;
2013
2014         // Create a java.lang.reflect.Constructor object.
2015
2016         java_lang_reflect_Constructor rc(m);
2017
2018         return rc.get_handle();
2019 }
2020 #endif
2021
2022
2023 /* class_get_enclosingmethod ***************************************************
2024
2025    Return the enclosing method for the given class.
2026
2027    IN:
2028        c ... class to return the enclosing method for
2029
2030    RETURN:
2031        methodinfo of the enclosing method
2032
2033 *******************************************************************************/
2034
2035 methodinfo *class_get_enclosingmethod_raw(classinfo *c)
2036 {
2037         constant_nameandtype *cn;
2038         classinfo            *ec;
2039         methodinfo           *m;
2040
2041         /* get enclosing class and method */
2042
2043         ec = class_get_enclosingclass(c);
2044         cn = c->enclosingmethod;
2045
2046         /* check for enclosing class and method */
2047
2048         if (ec == NULL)
2049                 return NULL;
2050
2051         if (cn == NULL)
2052                 return NULL;
2053
2054         /* find method in enclosing class */
2055
2056         m = class_findmethod(ec, cn->name, cn->descriptor);
2057
2058         if (m == NULL) {
2059                 exceptions_throw_internalerror("Enclosing method doesn't exist");
2060                 return NULL;
2061         }
2062
2063         return m;
2064 }
2065
2066
2067 /**
2068  * Return the enclosing method as java.lang.reflect.Method object for
2069  * the given class.
2070  *
2071  * @param c class to return the enclosing method for
2072  *
2073  * @return java.lang.reflect.Method object of the enclosing method
2074  */
2075 #if defined(ENABLE_JAVASE)
2076 java_handle_t* class_get_enclosingmethod(classinfo *c)
2077 {
2078         methodinfo*    m;
2079
2080         m = class_get_enclosingmethod_raw(c);
2081
2082         if (m == NULL)
2083                 return NULL;
2084
2085         /* check for <init> */
2086
2087         if (m->name == utf_init)
2088                 return NULL;
2089
2090         // Create a java.lang.reflect.Method object.
2091
2092         java_lang_reflect_Method rm(m);
2093
2094         return rm.get_handle();
2095 }
2096 #endif
2097
2098
2099 /* class_get_interfaces ********************************************************
2100
2101    Return an array of interfaces of the given class.
2102
2103 *******************************************************************************/
2104
2105 java_handle_objectarray_t *class_get_interfaces(classinfo *c)
2106 {
2107         classinfo                 *ic;
2108         java_handle_objectarray_t *oa;
2109         u4                         i;
2110
2111         if (!(c->state & CLASS_LINKED))
2112                 if (!link_class(c))
2113                         return NULL;
2114
2115         oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
2116
2117         if (oa == NULL)
2118                 return NULL;
2119
2120         for (i = 0; i < c->interfacescount; i++) {
2121                 ic = c->interfaces[i];
2122
2123                 LLNI_array_direct(oa, i) = (java_object_t *) ic;
2124         }
2125
2126         return oa;
2127 }
2128
2129
2130 /* class_get_annotations *******************************************************
2131
2132    Get the unparsed declared annotations in a byte array
2133    of the given class.
2134
2135    IN:
2136        c........the class of which the annotations should be returned
2137
2138    RETURN VALUE:
2139        The unparsed declared annotations in a byte array
2140        (or NULL if there aren't any).
2141
2142 *******************************************************************************/
2143
2144 java_handle_bytearray_t *class_get_annotations(classinfo *c)
2145 {
2146 #if defined(ENABLE_ANNOTATIONS)
2147         java_handle_t *annotations; /* unparsed annotations */
2148
2149         LLNI_classinfo_field_get(c, annotations, annotations);
2150
2151         return (java_handle_bytearray_t*)annotations;
2152 #else
2153         return NULL;
2154 #endif
2155 }
2156
2157
2158 /* class_get_modifiers *********************************************************
2159
2160    Get the modifier flags of the given class.
2161
2162    IN:
2163        c....the class of which the modifier flags should be returned
2164            ignoreInnerClassesAttrib
2165    RETURN VALUE:
2166        modifier flags
2167
2168 *******************************************************************************/
2169
2170 int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
2171 {
2172         classref_or_classinfo  inner;
2173         classref_or_classinfo  outer;
2174         utf                   *innername;
2175         int                    i;
2176         int32_t                flags;
2177
2178         /* default to flags of passed class */
2179
2180         flags = c->flags;
2181
2182         /* if requested we check if passed class is inner class */
2183
2184         if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
2185                 /* search for passed class as inner class */
2186
2187                 for (i = 0; i < c->innerclasscount; i++) {
2188                         inner = c->innerclass[i].inner_class;
2189                         outer = c->innerclass[i].outer_class;
2190
2191                         /* Check if inner is a classref or a real class and get
2192                the name of the structure */
2193
2194                         innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
2195
2196                         /* innerclass is this class */
2197
2198                         if (innername == c->name) {
2199                                 /* has the class actually an outer class? */
2200
2201                                 if (outer.any)
2202                                         /* return flags got from the outer class file */
2203                                         flags = c->innerclass[i].flags;
2204
2205                                 break;
2206                         }
2207                 }
2208         }
2209
2210         /* remove ACC_SUPER bit from flags */
2211
2212         return flags & ~ACC_SUPER & ACC_CLASS_REFLECT_MASK;
2213 }
2214
2215
2216 /* class_get_signature *********************************************************
2217
2218    Return the signature of the given class.  For array and primitive
2219    classes return NULL.
2220
2221 *******************************************************************************/
2222
2223 #if defined(ENABLE_JAVASE)
2224 utf *class_get_signature(classinfo *c)
2225 {
2226         /* For array and primitive classes return NULL. */
2227
2228         if (class_is_array(c) || class_is_primitive(c))
2229                 return NULL;
2230
2231         return c->signature;
2232 }
2233 #endif
2234
2235
2236 /* class_printflags ************************************************************
2237
2238    Prints flags of a class.
2239
2240 *******************************************************************************/
2241
2242 #if !defined(NDEBUG)
2243 void class_printflags(classinfo *c)
2244 {
2245         if (c == NULL) {
2246                 printf("NULL");
2247                 return;
2248         }
2249
2250         if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
2251         if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
2252         if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
2253         if (c->flags & ACC_STATIC)       printf(" STATIC");
2254         if (c->flags & ACC_FINAL)        printf(" FINAL");
2255         if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
2256         if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
2257         if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
2258         if (c->flags & ACC_NATIVE)       printf(" NATIVE");
2259         if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
2260         if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
2261 }
2262 #endif
2263
2264
2265 /* class_print *****************************************************************
2266
2267    Prints classname plus flags.
2268
2269 *******************************************************************************/
2270
2271 #if !defined(NDEBUG)
2272 void class_print(classinfo *c)
2273 {
2274         if (c == NULL) {
2275                 printf("NULL");
2276                 return;
2277         }
2278
2279         utf_display_printable_ascii(c->name);
2280         class_printflags(c);
2281 }
2282 #endif
2283
2284
2285 /* class_classref_print ********************************************************
2286
2287    Prints classname plus referer class.
2288
2289 *******************************************************************************/
2290
2291 #if !defined(NDEBUG)
2292 void class_classref_print(constant_classref *cr)
2293 {
2294         if (cr == NULL) {
2295                 printf("NULL");
2296                 return;
2297         }
2298
2299         utf_display_printable_ascii(cr->name);
2300         printf("(ref.by ");
2301         if (cr->referer)
2302                 class_print(cr->referer);
2303         else
2304                 printf("NULL");
2305         printf(")");
2306 }
2307 #endif
2308
2309
2310 /* class_println ***************************************************************
2311
2312    Prints classname plus flags and new line.
2313
2314 *******************************************************************************/
2315
2316 #if !defined(NDEBUG)
2317 void class_println(classinfo *c)
2318 {
2319         class_print(c);
2320         printf("\n");
2321 }
2322 #endif
2323
2324
2325 /* class_classref_println ******************************************************
2326
2327    Prints classname plus referer class and new line.
2328
2329 *******************************************************************************/
2330
2331 #if !defined(NDEBUG)
2332 void class_classref_println(constant_classref *cr)
2333 {
2334         class_classref_print(cr);
2335         printf("\n");
2336 }
2337 #endif
2338
2339
2340 /* class_classref_or_classinfo_print *******************************************
2341
2342    Prints classname plus referer class.
2343
2344 *******************************************************************************/
2345
2346 #if !defined(NDEBUG)
2347 void class_classref_or_classinfo_print(classref_or_classinfo c)
2348 {
2349         if (c.any == NULL) {
2350                 printf("(classref_or_classinfo) NULL");
2351                 return;
2352         }
2353         if (IS_CLASSREF(c))
2354                 class_classref_print(c.ref);
2355         else
2356                 class_print(c.cls);
2357 }
2358 #endif
2359
2360
2361 /* class_classref_or_classinfo_println *****************************************
2362
2363    Prints classname plus referer class and a newline.
2364
2365 *******************************************************************************/
2366
2367 #if !defined(NDEBUG)
2368 void class_classref_or_classinfo_println(classref_or_classinfo c)
2369 {
2370         class_classref_or_classinfo_print(c);
2371         printf("\n");
2372 }
2373 #endif
2374
2375
2376 /* class_showconstantpool ******************************************************
2377
2378    Dump the constant pool of the given class to stdout.
2379
2380 *******************************************************************************/
2381
2382 #if !defined(NDEBUG)
2383 void class_showconstantpool (classinfo *c) 
2384 {
2385         u4 i;
2386         void* e;
2387
2388         printf ("---- dump of constant pool ----\n");
2389
2390         for (i=0; i<c->cpcount; i++) {
2391                 printf ("#%d:  ", (int) i);
2392                 
2393                 e = c -> cpinfos [i];
2394                 if (e) {
2395                         
2396                         switch (c -> cptags [i]) {
2397                         case CONSTANT_Class:
2398                                 printf ("Classreference -> ");
2399                                 utf_display_printable_ascii ( ((constant_classref*)e) -> name );
2400                                 break;
2401                         case CONSTANT_Fieldref:
2402                                 printf ("Fieldref -> ");
2403                                 field_fieldref_print((constant_FMIref *) e);
2404                                 break;
2405                         case CONSTANT_Methodref:
2406                                 printf ("Methodref -> ");
2407                                 method_methodref_print((constant_FMIref *) e);
2408                                 break;
2409                         case CONSTANT_InterfaceMethodref:
2410                                 printf ("InterfaceMethod -> ");
2411                                 method_methodref_print((constant_FMIref *) e);
2412                                 break;
2413                         case CONSTANT_String:
2414                                 printf ("String -> ");
2415                                 utf_display_printable_ascii ((utf*) e);
2416                                 break;
2417                         case CONSTANT_Integer:
2418                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2419                                 break;
2420                         case CONSTANT_Float:
2421                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2422                                 break;
2423                         case CONSTANT_Double:
2424                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2425                                 break;
2426                         case CONSTANT_Long:
2427                                 printf ("Long -> %ld", (long int) ((constant_long*)e) -> value);
2428                                 break;
2429                         case CONSTANT_NameAndType:
2430                                 {
2431                                         constant_nameandtype *cnt = (constant_nameandtype *) e;
2432                                         printf ("NameAndType: ");
2433                                         utf_display_printable_ascii (cnt->name);
2434                                         printf (" ");
2435                                         utf_display_printable_ascii (cnt->descriptor);
2436                                 }
2437                                 break;
2438                         case CONSTANT_Utf8:
2439                                 printf ("Utf8 -> ");
2440                                 utf_display_printable_ascii ((utf*) e);
2441                                 break;
2442                         default: 
2443                                 log_text("Invalid type of ConstantPool-Entry");
2444                                 assert(0);
2445                         }
2446                 }
2447
2448                 printf ("\n");
2449         }
2450 }
2451 #endif /* !defined(NDEBUG) */
2452
2453
2454 /* class_showmethods ***********************************************************
2455
2456    Dump info about the fields and methods of the given class to stdout.
2457
2458 *******************************************************************************/
2459
2460 #if !defined(NDEBUG)
2461 void class_showmethods (classinfo *c)
2462 {
2463         s4 i;
2464         
2465         printf("--------- Fields and Methods ----------------\n");
2466         printf("Flags: ");
2467         class_printflags(c);
2468         printf("\n");
2469
2470         printf("This: ");
2471         utf_display_printable_ascii(c->name);
2472         printf("\n");
2473
2474         if (c->super) {
2475                 printf("Super: ");
2476                 utf_display_printable_ascii(c->super->name);
2477                 printf ("\n");
2478         }
2479
2480         printf("Index: %d\n", c->index);
2481         
2482         printf("Interfaces:\n");        
2483         for (i = 0; i < c->interfacescount; i++) {
2484                 printf("   ");
2485                 utf_display_printable_ascii(c->interfaces[i]->name);
2486                 printf (" (%d)\n", c->interfaces[i]->index);
2487         }
2488
2489         printf("Fields:\n");
2490         for (i = 0; i < c->fieldscount; i++)
2491                 field_println(&(c->fields[i]));
2492
2493         printf("Methods:\n");
2494         for (i = 0; i < c->methodscount; i++) {
2495                 methodinfo *m = &(c->methods[i]);
2496
2497                 if (!(m->flags & ACC_STATIC))
2498                         printf("vftblindex: %d   ", m->vftblindex);
2499
2500                 method_println(m);
2501         }
2502
2503         printf ("Virtual function table:\n");
2504         for (i = 0; i < c->vftbl->vftbllength; i++)
2505                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
2506 }
2507 #endif /* !defined(NDEBUG) */
2508
2509
2510 /*
2511  * These are local overrides for various environment variables in Emacs.
2512  * Please do not remove this and leave it at the end of the file, where
2513  * Emacs will automagically detect them.
2514  * ---------------------------------------------------------------------
2515  * Local variables:
2516  * mode: c
2517  * indent-tabs-mode: t
2518  * c-basic-offset: 4
2519  * tab-width: 4
2520  * End:
2521  * vim:noexpandtab:sw=4:ts=4:
2522  */