LCOV - code coverage report
Current view: top level - vm - class.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 492 810 60.7 %
Date: 2017-07-14 10:03:36 Functions: 47 59 79.7 %

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

Generated by: LCOV version 1.11