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

Generated by: LCOV version 1.11