LCOV - code coverage report
Current view: top level - vm - resolve.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 531 807 65.8 %
Date: 2017-07-14 10:03:36 Functions: 31 43 72.1 %

          Line data    Source code
       1             : /* src/vm/resolve.cpp - resolving classes/interfaces/fields/methods
       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             : 
      26             : #include "vm/resolve.hpp"
      27             : #include <assert.h>                     // for assert
      28             : #include <stdint.h>                     // for int32_t
      29             : #include "config.h"                     // for ENABLE_VERIFIER
      30             : #include "mm/dumpmemory.hpp"            // for DNEW
      31             : #include "mm/memory.hpp"
      32             : #include "toolbox/buffer.hpp"           // for Buffer
      33             : #include "vm/access.hpp"                // for access_is_accessible_member, etc
      34             : #include "vm/class.hpp"                 // for classinfo, etc
      35             : #include "vm/classcache.hpp"            // for classcache_add_constraint, etc
      36             : #include "vm/descriptor.hpp"            // for typedesc, methoddesc, etc
      37             : #include "vm/exceptions.hpp"
      38             : #include "vm/field.hpp"                 // for fieldinfo
      39             : #include "vm/global.hpp"                // for Type::TYPE_ADR, etc
      40             : #include "vm/globals.hpp"
      41             : #include "vm/jit/builtin.hpp"           // for builtin_instanceof
      42             : #include "vm/jit/ir/icmd.hpp"           // for ::ICMD_GETFIELD, etc
      43             : #include "vm/jit/ir/instruction.hpp"    // for instruction, etc
      44             : #include "vm/jit/jit.hpp"
      45             : #include "vm/jit/reg.hpp"               // for varinfo
      46             : #include "vm/jit/verify/typeinfo.hpp"   // for typeinfo_t, etc
      47             : #include "vm/linker.hpp"                // for link_class
      48             : #include "vm/loader.hpp"                // for load_class_from_classloader
      49             : #include "vm/method.hpp"                // for methodinfo
      50             : #include "vm/options.hpp"               // for opt_verify
      51             : #include "vm/primitive.hpp"             // for Primitive
      52             : #include "vm/types.hpp"                 // for s4
      53             : 
      54             : struct jitdata;
      55             : 
      56             : 
      57             : /******************************************************************************/
      58             : /* DEBUG HELPERS                                                              */
      59             : /******************************************************************************/
      60             : 
      61             : /*#define RESOLVE_VERBOSE*/
      62             : 
      63             : /* resolve_handle_pending_exception ********************************************
      64             : 
      65             :    Convert a pending ClassNotFoundException into a
      66             :    NoClassDefFoundError if requested.
      67             : 
      68             :    See: hotspot/src/share/vm/classfile/systemDictionary.cpp
      69             :    (handle_resolution_exception)
      70             : 
      71             :    ARGUMENTS:
      72             :        classname .... name of the class currently resolved
      73             :        throwError ... if true throw a NoClassDefFoundError instead of
      74             :                       a ClassNotFoundException
      75             : 
      76             : *******************************************************************************/
      77             : 
      78          15 : void resolve_handle_pending_exception(bool throwError)
      79             : {
      80             :         java_handle_t *e;
      81             : 
      82             :         /* Get the current exception. */
      83             : 
      84          15 :         e = exceptions_get_exception();
      85             : 
      86          15 :         if (e != NULL) {
      87          15 :                 if (throwError == true) {
      88             :                         /* Convert ClassNotFoundException to
      89             :                            NoClassDefFoundError. */
      90             : 
      91          15 :                         if (builtin_instanceof(e, class_java_lang_ClassNotFoundException)) {
      92             :                                 /* Clear exception, because we are calling Java code
      93             :                                    again. */
      94             : 
      95           3 :                                 exceptions_clear_exception();
      96             : 
      97             :                                 /* create new error */
      98             : 
      99           3 :                                 exceptions_throw_noclassdeffounderror_cause(e);
     100             :                         }
     101             :                         else {
     102          12 :                                 return;
     103             :                         }
     104             :                 }
     105             :                 else {
     106             :                         /* An exception conversion was not requested.  Simply
     107             :                            return. */
     108             : 
     109           0 :                         return;
     110             :                 }
     111             :         }
     112             : }
     113             : 
     114             : 
     115             : /******************************************************************************/
     116             : /* CLASS RESOLUTION                                                           */
     117             : /******************************************************************************/
     118             : 
     119             : /* resolve_class_from_name *****************************************************
     120             :  
     121             :    Resolve a symbolic class reference
     122             :   
     123             :    IN:
     124             :        referer..........the class containing the reference
     125             :        refmethod........the method from which resolution was triggered
     126             :                         (may be NULL if not applicable)
     127             :        classname........class name to resolve
     128             :        mode.............mode of resolution:
     129             :                             resolveLazy...only resolve if it does not
     130             :                                           require loading classes
     131             :                             resolveEager..load classes if necessary
     132             :            checkaccess......if true, access rights to the class are checked
     133             :            link.............if true, guarantee that the returned class, if any,
     134             :                             has been linked
     135             :   
     136             :    OUT:
     137             :        *result..........set to result of resolution, or to NULL if
     138             :                         the reference has not been resolved
     139             :                         In the case of an exception, *result is
     140             :                         guaranteed to be set to NULL.
     141             :   
     142             :    RETURN VALUE:
     143             :        true.............everything ok 
     144             :                         (*result may still be NULL for resolveLazy)
     145             :        false............an exception has been thrown
     146             : 
     147             :    NOTE:
     148             :        The returned class is *not* guaranteed to be linked!
     149             :            (It is guaranteed to be loaded, though.)
     150             :    
     151             : *******************************************************************************/
     152             : 
     153      882668 : bool resolve_class_from_name(classinfo *referer,
     154             :                                                          methodinfo *refmethod,
     155             :                                                          Utf8String classname,
     156             :                                                          resolve_mode_t mode,
     157             :                                                          bool checkaccess,
     158             :                                                          bool link,
     159             :                                                          classinfo **result)
     160             : {
     161             :         classinfo  *cls;
     162             :         const char *utf_ptr;
     163             :         int         len;
     164             : 
     165      882668 :         assert(result);
     166      882668 :         assert(referer);
     167      882668 :         assert(classname);
     168      882668 :         assert(mode == resolveLazy || mode == resolveEager);
     169             :         
     170      882668 :         *result = NULL;
     171             : 
     172             : #ifdef RESOLVE_VERBOSE
     173             :         printf("resolve_class_from_name(");
     174             :         utf_fprint_printable_ascii(stdout,referer->name);
     175             :         printf(",%p,",(void*)referer->classloader);
     176             :         utf_fprint_printable_ascii(stdout,classname);
     177             :         printf(",%d,%d)\n",(int)checkaccess,(int)link);
     178             : #endif
     179             : 
     180             :         /* lookup if this class has already been loaded */
     181             : 
     182      882668 :         cls = classcache_lookup(referer->classloader, classname);
     183             : 
     184             : #ifdef RESOLVE_VERBOSE
     185             :         printf("    lookup result: %p\n",(void*)cls);
     186             : #endif
     187             : 
     188      882668 :         if (!cls) {
     189             :                 /* resolve array types */
     190             : 
     191      252188 :                 if (classname[0] == '[') {
     192        7540 :                         utf_ptr = classname.begin() + 1;
     193        7540 :                         len     = classname.size()  - 1;
     194             : 
     195             :                         /* classname is an array type name */
     196             : 
     197        7540 :                         switch (*utf_ptr) {
     198             :                                 case 'L':
     199        6962 :                                         utf_ptr++;
     200        6962 :                                         len -= 2;
     201             :                                         /* FALLTHROUGH */
     202             :                                 case '[':
     203             :                                         /* the component type is a reference type */
     204             :                                         /* resolve the component type */
     205        7201 :                                         if (!resolve_class_from_name(referer,refmethod,
     206             :                                                                      Utf8String::from_utf8(utf_ptr,len),
     207             :                                                                      mode,checkaccess,link,&cls))
     208           0 :                                                 return false; /* exception */
     209        7201 :                                         if (!cls) {
     210        4320 :                                                 assert(mode == resolveLazy);
     211        4320 :                                                 return true; /* be lazy */
     212             :                                         }
     213             :                                         /* create the array class */
     214        2881 :                                         cls = class_array_of(cls,false);
     215        2881 :                                         if (!cls)
     216           0 :                                                 return false; /* exception */
     217             :                         }
     218             :                 }
     219             :                 else {
     220             :                         /* the class has not been loaded, yet */
     221      244648 :                         if (mode == resolveLazy)
     222      215415 :                                 return true; /* be lazy */
     223             :                 }
     224             : 
     225             : #ifdef RESOLVE_VERBOSE
     226             :                 printf("    loading...\n");
     227             : #endif
     228             : 
     229             :                 /* load the class */
     230             : 
     231       32453 :                 if (cls == NULL) {
     232       29572 :                         cls = load_class_from_classloader(classname, referer->classloader);
     233             : 
     234       29572 :                         if (cls == NULL)
     235          28 :                                 return false;
     236             :                 }
     237             :         }
     238             : 
     239             :         /* the class is now loaded */
     240      662905 :         assert(cls);
     241      662905 :         assert(cls->state & CLASS_LOADED);
     242             : 
     243             : #ifdef RESOLVE_VERBOSE
     244             :         printf("    checking access rights...\n");
     245             : #endif
     246             :         
     247             :         /* check access rights of referer to refered class */
     248             : 
     249      662905 :         if (checkaccess && !access_is_accessible_class(referer,cls)) {
     250           0 :                 Buffer<> buf;
     251             : 
     252             :                 Utf8String u = buf.write("class is not accessible (")
     253             :                                   .write_slash_to_dot(cls->name)
     254             :                                   .write(" from ")
     255             :                                   .write_slash_to_dot(referer->name)
     256             :                                   .write(")")
     257           0 :                                   .utf8_str();
     258             : 
     259           0 :                 exceptions_throw_illegalaccessexception(u);
     260           0 :                 return false; /* exception */
     261             :         }
     262             : 
     263             :         /* link the class if necessary */
     264      662905 :         if (link) {
     265      603877 :                 if (!(cls->state & CLASS_LINKED))
     266       19894 :                         if (!link_class(cls))
     267           0 :                                 return false; /* exception */
     268             : 
     269      603877 :                 assert(cls->state & CLASS_LINKED);
     270             :         }
     271             : 
     272             :         /* resolution succeeds */
     273             : #ifdef RESOLVE_VERBOSE
     274             :         printf("    success.\n");
     275             : #endif
     276      662905 :         *result = cls;
     277      662905 :         return true;
     278             : }
     279             : 
     280             : /* resolve_classref ************************************************************
     281             :  
     282             :    Resolve a symbolic class reference
     283             :   
     284             :    IN:
     285             :        refmethod........the method from which resolution was triggered
     286             :                         (may be NULL if not applicable)
     287             :        ref..............class reference
     288             :        mode.............mode of resolution:
     289             :                             resolveLazy...only resolve if it does not
     290             :                                           require loading classes
     291             :                             resolveEager..load classes if necessary
     292             :            checkaccess......if true, access rights to the class are checked
     293             :            link.............if true, guarantee that the returned class, if any,
     294             :                             has been linked
     295             :   
     296             :    OUT:
     297             :        *result..........set to result of resolution, or to NULL if
     298             :                         the reference has not been resolved
     299             :                         In the case of an exception, *result is
     300             :                         guaranteed to be set to NULL.
     301             :   
     302             :    RETURN VALUE:
     303             :        true.............everything ok 
     304             :                         (*result may still be NULL for resolveLazy)
     305             :        false............an exception has been thrown
     306             :    
     307             : *******************************************************************************/
     308             : 
     309      115612 : bool resolve_classref(methodinfo *refmethod,
     310             :                                           constant_classref *ref,
     311             :                                           resolve_mode_t mode,
     312             :                                           bool checkaccess,
     313             :                                           bool link,
     314             :                                           classinfo **result)
     315             : {
     316      115612 :         return resolve_classref_or_classinfo(refmethod,to_classref_or_classinfo(ref),mode,checkaccess,link,result);
     317             : }
     318             : 
     319             : /* resolve_classref_or_classinfo ***********************************************
     320             :  
     321             :    Resolve a symbolic class reference if necessary
     322             : 
     323             :    NOTE: If given, refmethod->clazz is used as the referring class.
     324             :          Otherwise, cls.ref->referer is used.
     325             : 
     326             :    IN:
     327             :        refmethod........the method from which resolution was triggered
     328             :                         (may be NULL if not applicable)
     329             :        cls..............class reference or classinfo
     330             :        mode.............mode of resolution:
     331             :                             resolveLazy...only resolve if it does not
     332             :                                           require loading classes
     333             :                             resolveEager..load classes if necessary
     334             :            checkaccess......if true, access rights to the class are checked
     335             :            link.............if true, guarantee that the returned class, if any,
     336             :                             has been linked
     337             :   
     338             :    OUT:
     339             :        *result..........set to result of resolution, or to NULL if
     340             :                         the reference has not been resolved
     341             :                         In the case of an exception, *result is
     342             :                         guaranteed to be set to NULL.
     343             :   
     344             :    RETURN VALUE:
     345             :        true.............everything ok 
     346             :                         (*result may still be NULL for resolveLazy)
     347             :        false............an exception has been thrown
     348             : 
     349             : *******************************************************************************/
     350             : 
     351      706438 : bool resolve_classref_or_classinfo(methodinfo *refmethod,
     352             :                                                                    classref_or_classinfo cls,
     353             :                                                                    resolve_mode_t mode,
     354             :                                                                    bool checkaccess,
     355             :                                                                    bool link,
     356             :                                                                    classinfo **result)
     357             : {
     358             :         classinfo         *c;
     359             :         classinfo         *referer;
     360             : 
     361      706438 :         assert(cls.any);
     362      706438 :         assert(mode == resolveEager || mode == resolveLazy);
     363      706438 :         assert(result);
     364             : 
     365             : #ifdef RESOLVE_VERBOSE
     366             :         printf("resolve_classref_or_classinfo(");
     367             :         utf_fprint_printable_ascii(stdout, CLASSREF_OR_CLASSINFO_NAME(cls));
     368             :         printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
     369             : #endif
     370             : 
     371      706438 :         *result = NULL;
     372             : 
     373      706438 :         if (cls.is_classref()) {
     374             :                 /* we must resolve this reference */
     375             : 
     376             :                 /* determine which class to use as the referer */
     377             : 
     378             :                 /* Common cases are refmethod == NULL or both referring classes */
     379             :                 /* being the same, so the referer usually is cls.ref->referer.    */
     380             :                 /* There is one important case where it is not: When we do a      */
     381             :                 /* deferred assignability check to a formal argument of a method, */
     382             :                 /* we must use refmethod->clazz (the caller's class) to resolve   */
     383             :                 /* the type of the formal argument.                               */
     384             : 
     385      580616 :                 referer = (refmethod) ? refmethod->clazz : cls.ref->referer;
     386             : 
     387      580616 :                 if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
     388             :                                                                          mode, checkaccess, link, &c))
     389          25 :                         goto return_exception;
     390             : 
     391             :         } else {
     392             :                 /* cls has already been resolved */
     393      125822 :                 c = cls.cls;
     394      125822 :                 assert(c->state & CLASS_LOADED);
     395             :         }
     396      706413 :         assert(c || (mode == resolveLazy));
     397             : 
     398      706413 :         if (!c)
     399      138154 :                 return true; /* be lazy */
     400             :         
     401      568259 :         assert(c);
     402      568259 :         assert(c->state & CLASS_LOADED);
     403             : 
     404      568259 :         if (link) {
     405      509333 :                 if (!(c->state & CLASS_LINKED))
     406           0 :                         if (!link_class(c))
     407           0 :                                 goto return_exception;
     408             : 
     409      509333 :                 assert(c->state & CLASS_LINKED);
     410             :         }
     411             : 
     412             :         /* succeeded */
     413      568259 :         *result = c;
     414      568259 :         return true;
     415             : 
     416             :  return_exception:
     417          25 :         *result = NULL;
     418          25 :         return false;
     419             : }
     420             : 
     421             : 
     422             : /* resolve_classref_or_classinfo_eager *****************************************
     423             :  
     424             :    Resolve a symbolic class reference eagerly if necessary.
     425             :    No attempt is made to link the class.
     426             : 
     427             :    IN:
     428             :        cls..............class reference or classinfo
     429             :        checkaccess......if true, access rights to the class are checked
     430             :   
     431             :    RETURN VALUE:
     432             :        classinfo *......the resolved class
     433             :        NULL.............an exception has been thrown
     434             :    
     435             : *******************************************************************************/
     436             : 
     437       56108 : classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
     438             :                                                                                            bool checkaccess)
     439             : {
     440             :         classinfo *c;
     441             : 
     442       56108 :         if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
     443           2 :                 return NULL;
     444             : 
     445       56106 :         return c;
     446             : }
     447             : 
     448             : 
     449             : /* resolve_class_from_typedesc *************************************************
     450             :  
     451             :    Return a classinfo * for the given type descriptor
     452             :   
     453             :    IN:
     454             :        d................type descriptor
     455             :            checkaccess......if true, access rights to the class are checked
     456             :            link.............if true, guarantee that the returned class, if any,
     457             :                             has been linked
     458             :    OUT:
     459             :        *result..........set to result of resolution, or to NULL if
     460             :                         the reference has not been resolved
     461             :                         In the case of an exception, *result is
     462             :                         guaranteed to be set to NULL.
     463             :   
     464             :    RETURN VALUE:
     465             :        true.............everything ok 
     466             :        false............an exception has been thrown
     467             : 
     468             :    NOTE:
     469             :        This function always resolves eagerly.
     470             :    
     471             : *******************************************************************************/
     472             : 
     473        1910 : bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
     474             : {
     475             :         classinfo *cls;
     476             :         
     477        1910 :         assert(d);
     478        1910 :         assert(result);
     479             : 
     480        1910 :         *result = NULL;
     481             : 
     482             : #ifdef RESOLVE_VERBOSE
     483             :         printf("resolve_class_from_typedesc(");
     484             :         descriptor_debug_print_typedesc(stdout,d);
     485             :         printf(",%i,%i)\n",(int)checkaccess,(int)link);
     486             : #endif
     487             : 
     488        1910 :         if (d->type == TYPE_ADR) {
     489             :                 /* a reference type */
     490        1517 :                 assert(d->classref);
     491        1517 :                 if (!resolve_classref_or_classinfo(NULL,to_classref_or_classinfo(d->classref),
     492             :                                                                                    resolveEager,checkaccess,link,&cls))
     493           0 :                         return false; /* exception */
     494             :         }
     495             :         else {
     496             :                 /* a primitive type */
     497             : 
     498         393 :                 cls = Primitive::get_class_by_type(d->primitivetype);
     499             : 
     500         393 :                 assert(cls->state & CLASS_LOADED);
     501             : 
     502         393 :                 if (!(cls->state & CLASS_LINKED))
     503           0 :                         if (!link_class(cls))
     504           0 :                                 return false; /* exception */
     505             :         }
     506             : 
     507        1910 :         assert(cls);
     508        1910 :         assert(cls->state & CLASS_LOADED);
     509        1910 :         assert(!link || (cls->state & CLASS_LINKED));
     510             : 
     511             : #ifdef RESOLVE_VERBOSE
     512             :         printf("    result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
     513             : #endif
     514             : 
     515        1910 :         *result = cls;
     516        1910 :         return true;
     517             : }
     518             : 
     519             : /******************************************************************************/
     520             : /* SUBTYPE SET CHECKS                                                         */
     521             : /******************************************************************************/
     522             : 
     523             : /* resolve_subtype_check *******************************************************
     524             :  
     525             :    Resolve the given types lazily and perform a subtype check
     526             :   
     527             :    IN:
     528             :        refmethod........the method triggering the resolution
     529             :        subtype..........checked to be a subtype of supertype
     530             :            supertype........the super type to check agaings
     531             :            mode.............mode of resolution:
     532             :                             resolveLazy...only resolve if it does not
     533             :                                           require loading classes
     534             :                             resolveEager..load classes if necessary
     535             :        error............which type of exception to throw if
     536             :                         the test fails. May be:
     537             :                             resolveLinkageError, or
     538             :                             resolveIllegalAccessError
     539             :                                                 IMPORTANT: If error==resolveIllegalAccessError,
     540             :                                                 then array types are not checked.
     541             : 
     542             :    RETURN VALUE:
     543             :        resolveSucceeded.....the check succeeded
     544             :        resolveDeferred......the check could not be performed due to
     545             :                                 unresolved types. (This can only happen for
     546             :                                                         mode == resolveLazy.)
     547             :            resolveFailed........the check failed, an exception has been thrown.
     548             :    
     549             :    NOTE:
     550             :            The types are resolved first, so any
     551             :            exception which may occurr during resolution may
     552             :            be thrown by this function.
     553             :    
     554             : *******************************************************************************/
     555             : 
     556             : #if defined(ENABLE_VERIFIER)
     557       55839 : static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
     558             :                                                                                       classref_or_classinfo subtype,
     559             :                                                                                           classref_or_classinfo supertype,
     560             :                                                                                           resolve_mode_t mode,
     561             :                                                                                           resolve_err_t error)
     562             : {
     563             :         classinfo        *subclass;
     564             :         typeinfo_t        subti;
     565             :         typecheck_result  r;
     566             : 
     567       55839 :         assert(refmethod);
     568       55839 :         assert(subtype.any);
     569       55839 :         assert(supertype.any);
     570       55839 :         assert(mode == resolveLazy || mode == resolveEager);
     571       55839 :         assert(error == resolveLinkageError || error == resolveIllegalAccessError);
     572             : 
     573             :         /* resolve the subtype */
     574             : 
     575       55839 :         if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
     576             :                 /* the subclass could not be resolved. therefore we are sure that  */
     577             :                 /* no instances of this subclass will ever exist -> skip this test */
     578             :                 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
     579          22 :                 exceptions_clear_exception();
     580          22 :                 return resolveSucceeded;
     581             :         }
     582       55817 :         if (!subclass)
     583        7829 :                 return resolveDeferred; /* be lazy */
     584             : 
     585       47988 :         assert(subclass->state & CLASS_LINKED);
     586             : 
     587             :         /* do not check access to protected members of arrays */
     588             : 
     589       47988 :         if (error == resolveIllegalAccessError && subclass->name[0] == '[') {
     590           0 :                 return resolveSucceeded;
     591             :         }
     592             : 
     593             :         /* perform the subtype check */
     594             : 
     595       47988 :         subti.init_class(subclass);
     596             : check_again:
     597       47988 :         r = subti.is_assignable_to_class(supertype);
     598       47988 :         if (r == typecheck_FAIL)
     599           0 :                 return resolveFailed; /* failed, exception is already set */
     600             : 
     601       47988 :         if (r == typecheck_MAYBE) {
     602        3291 :                 assert(supertype.is_classref());
     603        3291 :                 if (mode == resolveEager) {
     604           0 :                         if (!resolve_classref_or_classinfo(refmethod,supertype,
     605             :                                                                                            resolveEager,false,true,
     606             :                                                                                            &supertype.cls))
     607             :                         {
     608           0 :                                 return resolveFailed;
     609             :                         }
     610           0 :                         assert(supertype.cls);
     611           0 :                         goto check_again;
     612             :                 }
     613             : 
     614        3291 :                 return resolveDeferred; /* be lazy */
     615             :         }
     616             : 
     617       44697 :         if (!r) {
     618             :                 /* sub class relationship is false */
     619             : 
     620             : #if defined(RESOLVE_VERBOSE)
     621             :                 printf("SUBTYPE CHECK FAILED!\n");
     622             : #endif
     623           5 :                 Buffer<> buf;
     624             : 
     625           5 :                 if (error == resolveIllegalAccessError)
     626           0 :                         buf.write("illegal access to protected member (");
     627             :                 else
     628           5 :                         buf.write("subtype constraint violated (");
     629             :         
     630             :                 buf.write_slash_to_dot(subclass->name)
     631             :                    .write(" is not a subclass of ")
     632             :                    .write_slash_to_dot(CLASSREF_OR_CLASSINFO_NAME(supertype))
     633           5 :                    .write(')');
     634             : 
     635           5 :                 if (error == resolveIllegalAccessError)
     636           0 :                         exceptions_throw_illegalaccessexception(buf.utf8_str());
     637             :                 else
     638           5 :                         exceptions_throw_linkageerror(buf.c_str(), NULL);
     639             : 
     640           5 :                 return resolveFailed; /* exception */
     641             :         }
     642             : 
     643             :         /* everything ok */
     644             : 
     645       44692 :         return resolveSucceeded;
     646             : }
     647             : #endif /* defined(ENABLE_VERIFIER) */
     648             : 
     649             : /* resolve_lazy_subtype_checks *************************************************
     650             :  
     651             :    Resolve the types to check lazily and perform subtype checks
     652             :   
     653             :    IN:
     654             :        refmethod........the method triggering the resolution
     655             :        subtinfo.........the typeinfo containing the subtypes
     656             :        supertype........the supertype to test againgst
     657             :            mode.............mode of resolution:
     658             :                             resolveLazy...only resolve if it does not
     659             :                                           require loading classes
     660             :                             resolveEager..load classes if necessary
     661             :        error............which type of exception to throw if
     662             :                         the test fails. May be:
     663             :                             resolveLinkageError, or
     664             :                             resolveIllegalAccessError
     665             :                                                 IMPORTANT: If error==resolveIllegalAccessError,
     666             :                                                 then array types in the set are skipped.
     667             : 
     668             :    RETURN VALUE:
     669             :        resolveSucceeded.....the check succeeded
     670             :        resolveDeferred......the check could not be performed due to
     671             :                                 unresolved types
     672             :            resolveFailed........the check failed, an exception has been thrown.
     673             :    
     674             :    NOTE:
     675             :        The references in the set are resolved first, so any
     676             :        exception which may occurr during resolution may
     677             :        be thrown by this function.
     678             :    
     679             : *******************************************************************************/
     680             : 
     681             : #if defined(ENABLE_VERIFIER)
     682      535567 : static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
     683             :                                                                                                         typeinfo_t *subtinfo,
     684             :                                                                                                         classref_or_classinfo supertype,
     685             :                                                                                                         resolve_err_t error)
     686             : {
     687             :         int count;
     688             :         int i;
     689             :         resolve_result_t result;
     690             : 
     691      535567 :         assert(refmethod);
     692      535567 :         assert(subtinfo);
     693      535567 :         assert(supertype.any);
     694      535567 :         assert(error == resolveLinkageError || error == resolveIllegalAccessError);
     695             : 
     696             :         /* returnAddresses are illegal here */
     697             : 
     698      535567 :         if (subtinfo->is_primitive()) {
     699             :                 exceptions_throw_verifyerror(refmethod,
     700           0 :                                 "Invalid use of returnAddress");
     701           0 :                 return resolveFailed;
     702             :         }
     703             : 
     704             :         /* uninitialized objects are illegal here */
     705             : 
     706      535567 :         if (subtinfo->is_newobject()) {
     707             :                 exceptions_throw_verifyerror(refmethod,
     708           0 :                                 "Invalid use of uninitialized object");
     709           0 :                 return resolveFailed;
     710             :         }
     711             : 
     712             :         /* the nulltype is always assignable */
     713             : 
     714      535567 :         if (subtinfo->is_nulltype())
     715        8528 :                 return resolveSucceeded;
     716             : 
     717             :         /* every type is assignable to (BOOTSTRAP)java.lang.Object */
     718             : 
     719      527039 :         if (supertype.cls == class_java_lang_Object
     720             :                 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf8::java_lang_Object
     721             :                         && refmethod->clazz->classloader == NULL))
     722             :         {
     723       41362 :                 return resolveSucceeded;
     724             :         }
     725             : 
     726      485677 :         if (subtinfo->merged) {
     727             : 
     728             :                 /* for a merged type we have to do a series of checks */
     729             : 
     730         357 :                 count = subtinfo->merged->count;
     731         687 :                 for (i=0; i<count; ++i) {
     732         687 :                         classref_or_classinfo c = subtinfo->merged->list[i];
     733         687 :                         if (subtinfo->dimension > 0) {
     734             :                                 /* a merge of array types */
     735             :                                 /* the merged list contains the possible _element_ types, */
     736             :                                 /* so we have to create array types with these elements.  */
     737           0 :                                 if (c.is_classref()) {
     738           0 :                                         c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
     739             :                                 }
     740             :                                 else {
     741           0 :                                         c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
     742             :                                 }
     743             :                         }
     744             : 
     745             :                         /* do the subtype check against the type c */
     746             : 
     747         687 :                         result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
     748         687 :                         if (result != resolveSucceeded)
     749         357 :                                 return result;
     750             :                 }
     751             :         }
     752             :         else {
     753             : 
     754             :                 /* a single type, this is the common case, hopefully */
     755             : 
     756      485320 :                 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
     757             :                         == CLASSREF_OR_CLASSINFO_NAME(supertype))
     758             :                 {
     759             :                         /* the class names are the same */
     760             :                     /* equality is guaranteed by the loading constraints */
     761      444955 :                         return resolveSucceeded;
     762             :                 }
     763             :                 else {
     764             : 
     765             :                         /* some other type name, try to perform the check lazily */
     766             : 
     767             :                         return resolve_subtype_check(refmethod,
     768             :                                                                                  subtinfo->typeclass,supertype,
     769             :                                                                                  resolveLazy,
     770       40365 :                                                                                  error);
     771             :                 }
     772             :         }
     773             : 
     774             :         /* everything ok */
     775           0 :         return resolveSucceeded;
     776             : }
     777             : #endif /* defined(ENABLE_VERIFIER) */
     778             : 
     779             : /* resolve_and_check_subtype_set ***********************************************
     780             :  
     781             :    Resolve the references in the given set and test subtype relationships
     782             :   
     783             :    IN:
     784             :        refmethod........the method triggering the resolution
     785             :        ref..............a set of class/interface references
     786             :                         (may be empty)
     787             :        typeref..........the type to test against the set
     788             :        mode.............mode of resolution:
     789             :                             resolveLazy...only resolve if it does not
     790             :                                           require loading classes
     791             :                             resolveEager..load classes if necessary
     792             :        error............which type of exception to throw if
     793             :                         the test fails. May be:
     794             :                             resolveLinkageError, or
     795             :                             resolveIllegalAccessError
     796             :                                                 IMPORTANT: If error==resolveIllegalAccessError,
     797             :                                                 then array types in the set are skipped.
     798             : 
     799             :    RETURN VALUE:
     800             :        resolveSucceeded.....the check succeeded
     801             :        resolveDeferred......the check could not be performed due to
     802             :                                 unresolved types. (This can only happen if
     803             :                                                         mode == resolveLazy.)
     804             :            resolveFailed........the check failed, an exception has been thrown.
     805             :    
     806             :    NOTE:
     807             :        The references in the set are resolved first, so any
     808             :        exception which may occurr during resolution may
     809             :        be thrown by this function.
     810             :    
     811             : *******************************************************************************/
     812             : 
     813             : #if defined(ENABLE_VERIFIER)
     814       59049 : static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
     815             :                                                                           unresolved_subtype_set *ref,
     816             :                                                                           classref_or_classinfo typeref,
     817             :                                                                           resolve_mode_t mode,
     818             :                                                                           resolve_err_t error)
     819             : {
     820             :         classref_or_classinfo *setp;
     821             :         resolve_result_t checkresult;
     822             : 
     823       59049 :         assert(refmethod);
     824       59049 :         assert(ref);
     825       59049 :         assert(typeref.any);
     826       59049 :         assert(mode == resolveLazy || mode == resolveEager);
     827       59049 :         assert(error == resolveLinkageError || error == resolveIllegalAccessError);
     828             : 
     829             : #if defined(RESOLVE_VERBOSE)
     830             :         printf("resolve_and_check_subtype_set:\n");
     831             :         unresolved_subtype_set_debug_dump(ref, stdout);
     832             :         if (typeref.is_classref())
     833             :                 class_classref_println(typeref.ref);
     834             :         else
     835             :                 class_println(typeref.cls);
     836             : #endif
     837             : 
     838       59049 :         setp = ref->subtyperefs;
     839             : 
     840             :         /* an empty set of tests always succeeds */
     841       59049 :         if (!setp || !setp->any) {
     842       45589 :                 return resolveSucceeded;
     843             :         }
     844             : 
     845             :         /* first resolve the type if necessary */
     846       13460 :         if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
     847           0 :                 return resolveFailed; /* exception */
     848       13460 :         if (!typeref.cls)
     849           0 :                 return resolveDeferred; /* be lazy */
     850             : 
     851       13460 :         assert(typeref.cls->state & CLASS_LINKED);
     852             : 
     853             :         /* iterate over the set members */
     854             : 
     855       28242 :         for (; setp->any; ++setp) {
     856       14787 :                 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
     857             : #if defined(RESOLVE_VERBOSE)
     858             :                 if (checkresult != resolveSucceeded)
     859             :                         printf("SUBTYPE CHECK FAILED!\n");
     860             : #endif
     861       14787 :                 if (checkresult != resolveSucceeded)
     862           5 :                         return checkresult;
     863             :         }
     864             : 
     865             :         /* check succeeds */
     866       13455 :         return resolveSucceeded;
     867             : }
     868             : #endif /* defined(ENABLE_VERIFIER) */
     869             : 
     870             : /******************************************************************************/
     871             : /* CLASS RESOLUTION                                                           */
     872             : /******************************************************************************/
     873             : 
     874             : /* resolve_class ***************************************************************
     875             :  
     876             :    Resolve an unresolved class reference. The class is also linked.
     877             :   
     878             :    IN:
     879             :        ref..............struct containing the reference
     880             :        mode.............mode of resolution:
     881             :                             resolveLazy...only resolve if it does not
     882             :                                           require loading classes
     883             :                             resolveEager..load classes if necessary
     884             :            checkaccess......if true, access rights to the class are checked
     885             :    
     886             :    OUT:
     887             :        *result..........set to the result of resolution, or to NULL if
     888             :                         the reference has not been resolved
     889             :                         In the case of an exception, *result is
     890             :                         guaranteed to be set to NULL.
     891             :   
     892             :    RETURN VALUE:
     893             :        true.............everything ok 
     894             :                         (*result may still be NULL for resolveLazy)
     895             :        false............an exception has been thrown
     896             :    
     897             : *******************************************************************************/
     898             : 
     899             : #ifdef ENABLE_VERIFIER
     900        2990 : bool resolve_class(unresolved_class *ref,
     901             :                                    resolve_mode_t mode,
     902             :                                    bool checkaccess,
     903             :                                    classinfo **result)
     904             : {
     905             :         classinfo *cls;
     906             :         resolve_result_t checkresult;
     907             :         
     908        2990 :         assert(ref);
     909        2990 :         assert(result);
     910        2990 :         assert(mode == resolveLazy || mode == resolveEager);
     911             : 
     912        2990 :         *result = NULL;
     913             : 
     914             : #ifdef RESOLVE_VERBOSE
     915             :         unresolved_class_debug_dump(ref,stdout);
     916             : #endif
     917             : 
     918             :         /* first we must resolve the class */
     919        2990 :         if (!resolve_classref(ref->referermethod,
     920             :                                               ref->classref,mode,checkaccess,true,&cls))
     921             :         {
     922             :                 /* the class reference could not be resolved */
     923           0 :                 return false; /* exception */
     924             :         }
     925        2990 :         if (!cls)
     926           0 :                 return true; /* be lazy */
     927             : 
     928        2990 :         assert(cls);
     929        2990 :         assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
     930             : 
     931             :         /* now we check the subtype constraints */
     932             :         
     933             :         checkresult = resolve_and_check_subtype_set(ref->referermethod,
     934             :                                                                            &(ref->subtypeconstraints),
     935             :                                                                            to_classref_or_classinfo(cls),
     936             :                                                                            mode,
     937        2990 :                                                                            resolveLinkageError);
     938        2990 :         if (checkresult != resolveSucceeded)
     939           3 :                 return (bool) checkresult;
     940             : 
     941             :         /* succeed */
     942        2987 :         *result = cls;
     943        2987 :         return true;
     944             : }
     945             : #endif /* ENABLE_VERIFIER */
     946             : 
     947             : /* resolve_classref_eager ******************************************************
     948             :  
     949             :    Resolve an unresolved class reference eagerly. The class is also linked and
     950             :    access rights to the class are checked.
     951             :   
     952             :    IN:
     953             :        ref..............constant_classref to the class
     954             :    
     955             :    RETURN VALUE:
     956             :        classinfo * to the class, or
     957             :            NULL if an exception has been thrown
     958             :    
     959             : *******************************************************************************/
     960             : 
     961       15398 : classinfo * resolve_classref_eager(constant_classref *ref)
     962             : {
     963             :         classinfo *c;
     964             : 
     965       15398 :         if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
     966           1 :                 return NULL;
     967             : 
     968       15397 :         return c;
     969             : }
     970             : 
     971             : /* resolve_classref_eager_nonabstract ******************************************
     972             :  
     973             :    Resolve an unresolved class reference eagerly. The class is also linked and
     974             :    access rights to the class are checked. A check is performed that the class
     975             :    is not abstract.
     976             :   
     977             :    IN:
     978             :        ref..............constant_classref to the class
     979             :    
     980             :    RETURN VALUE:
     981             :        classinfo * to the class, or
     982             :            NULL if an exception has been thrown
     983             :    
     984             : *******************************************************************************/
     985             : 
     986           0 : classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
     987             : {
     988             :         classinfo *c;
     989             : 
     990           0 :         if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
     991           0 :                 return NULL;
     992             : 
     993             :         /* ensure that the class is not abstract */
     994             : 
     995           0 :         if (c->flags & ACC_ABSTRACT) {
     996           0 :                 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
     997           0 :                 return NULL;
     998             :         }
     999             : 
    1000           0 :         return c;
    1001             : }
    1002             : 
    1003             : /* resolve_class_eager *********************************************************
    1004             :  
    1005             :    Resolve an unresolved class reference eagerly. The class is also linked and
    1006             :    access rights to the class are checked.
    1007             :   
    1008             :    IN:
    1009             :        ref..............struct containing the reference
    1010             :    
    1011             :    RETURN VALUE:
    1012             :        classinfo * to the class, or
    1013             :            NULL if an exception has been thrown
    1014             :    
    1015             : *******************************************************************************/
    1016             : 
    1017             : #ifdef ENABLE_VERIFIER
    1018           0 : classinfo * resolve_class_eager(unresolved_class *ref)
    1019             : {
    1020             :         classinfo *c;
    1021             : 
    1022           0 :         if (!resolve_class(ref,resolveEager,true,&c))
    1023           0 :                 return NULL;
    1024             : 
    1025           0 :         return c;
    1026             : }
    1027             : #endif /* ENABLE_VERIFIER */
    1028             : 
    1029             : /* resolve_class_eager_no_access_check *****************************************
    1030             :  
    1031             :    Resolve an unresolved class reference eagerly. The class is also linked.
    1032             :    Access rights are _not_ checked.
    1033             :   
    1034             :    IN:
    1035             :        ref..............struct containing the reference
    1036             :    
    1037             :    RETURN VALUE:
    1038             :        classinfo * to the class, or
    1039             :            NULL if an exception has been thrown
    1040             :    
    1041             : *******************************************************************************/
    1042             : 
    1043             : #ifdef ENABLE_VERIFIER
    1044        2990 : classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
    1045             : {
    1046             :         classinfo *c;
    1047             : 
    1048        2990 :         if (!resolve_class(ref, resolveEager, false, &c))
    1049           3 :                 return NULL;
    1050             : 
    1051        2987 :         return c;
    1052             : }
    1053             : #endif /* ENABLE_VERIFIER */
    1054             : 
    1055             : /******************************************************************************/
    1056             : /* FIELD RESOLUTION                                                           */
    1057             : /******************************************************************************/
    1058             : 
    1059             : /* resolve_field_verifier_checks *******************************************
    1060             :  
    1061             :    Do the verifier checks necessary after field has been resolved.
    1062             :   
    1063             :    IN:
    1064             :        refmethod........the method containing the reference
    1065             :            fieldref.........the field reference
    1066             :            container........the class where the field was found
    1067             :            fi...............the fieldinfo of the resolved field
    1068             :            instanceti.......instance typeinfo, if available
    1069             :            valueti..........value typeinfo, if available
    1070             :            isstatic.........true if this is a *STATIC* instruction
    1071             :            isput............true if this is a PUT* instruction
    1072             :   
    1073             :    RETURN VALUE:
    1074             :        resolveSucceeded....everything ok
    1075             :            resolveDeferred.....tests could not be done, have been deferred
    1076             :        resolveFailed.......exception has been thrown
    1077             :    
    1078             : *******************************************************************************/
    1079             : 
    1080             : #if defined(ENABLE_VERIFIER)
    1081      224523 : resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
    1082             :                                                                                            constant_FMIref *fieldref,
    1083             :                                                                                            classinfo *container,
    1084             :                                                                                            fieldinfo *fi,
    1085             :                                                                                            typeinfo_t *instanceti,
    1086             :                                                                                            typeinfo_t *valueti,
    1087             :                                                                                            bool isstatic,
    1088             :                                                                                            bool isput)
    1089             : {
    1090             :         classinfo         *declarer;
    1091             :         classinfo         *referer;
    1092             :         resolve_result_t   result;
    1093             :         constant_classref *fieldtyperef;
    1094             : 
    1095      224523 :         assert(refmethod);
    1096      224523 :         assert(fieldref);
    1097      224523 :         assert(container);
    1098      224523 :         assert(fi);
    1099             : 
    1100             :         /* get the classinfos and the field type */
    1101             : 
    1102      224523 :         referer = refmethod->clazz;
    1103      224523 :         assert(referer);
    1104             : 
    1105      224523 :         declarer = fi->clazz;
    1106      224523 :         assert(declarer);
    1107      224523 :         assert(referer->state & CLASS_LINKED);
    1108             : 
    1109      224523 :         fieldtyperef = fieldref->parseddesc.fd->classref;
    1110             : 
    1111             :         /* check static */
    1112             : 
    1113             : #if true != 1
    1114             : #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
    1115             : #endif
    1116             : 
    1117      224523 :         if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
    1118             :                 /* a static field is accessed via an instance, or vice versa */
    1119             :                 exceptions_throw_incompatibleclasschangeerror(declarer,
    1120             :                                                                                                           (fi->flags & ACC_STATIC)
    1121             :                                                                                                           ? "static field accessed via instance"
    1122           0 :                                                                                                           : "instance field  accessed without instance");
    1123             : 
    1124           0 :                 return resolveFailed;
    1125             :         }
    1126             : 
    1127             :         /* check access rights */
    1128             : 
    1129      224523 :         if (!access_is_accessible_member(referer,declarer,fi->flags)) {
    1130           0 :                 Buffer<> buf(64);
    1131             : 
    1132             :                 Utf8String u = buf.write("field is not accessible (")
    1133             :                                   .write_slash_to_dot(declarer->name)
    1134             :                                   .write(".")
    1135             :                                   .write(fi->name)
    1136             :                                   .write(" from ")
    1137             :                                   .write_slash_to_dot(referer->name)
    1138             :                                   .write(")")
    1139           0 :                                   .utf8_str();
    1140             : 
    1141           0 :                 exceptions_throw_illegalaccessexception(u);
    1142             : 
    1143           0 :                 return resolveFailed; /* exception */
    1144             :         }
    1145             : 
    1146             :         /* for non-static methods we have to check the constraints on the         */
    1147             :         /* instance type                                                          */
    1148             : 
    1149      224523 :         if (instanceti) {
    1150             :                 typeinfo_t *insttip;
    1151             :                 typeinfo_t tinfo;
    1152             : 
    1153             :                 /* The instanceslot must contain a reference to a non-array type */
    1154             : 
    1155      152771 :                 if (!instanceti->is_reference()) {
    1156           0 :                         exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
    1157           0 :                         return resolveFailed;
    1158             :                 }
    1159      152771 :                 if (instanceti->is_array()) {
    1160           0 :                         exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
    1161           0 :                         return resolveFailed;
    1162             :                 }
    1163             : 
    1164      152771 :                 if (isput && instanceti->is_newobject())
    1165             :                 {
    1166             :                         /* The instruction writes a field in an uninitialized object. */
    1167             :                         /* This is only allowed when a field of an uninitialized 'this' object is */
    1168             :                         /* written inside an initialization method                                */
    1169             : 
    1170             :                         classinfo *initclass;
    1171        1502 :                         instruction *ins = instanceti->newobject_instruction();
    1172             : 
    1173        1502 :                         if (ins != NULL) {
    1174           0 :                                 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
    1175           0 :                                 return resolveFailed;
    1176             :                         }
    1177             : 
    1178             :                         /* XXX check that class of field == refmethod->clazz */
    1179        1502 :                         initclass = referer; /* XXX classrefs */
    1180        1502 :                         assert(initclass->state & CLASS_LINKED);
    1181             : 
    1182        1502 :                         tinfo.init_class(initclass);
    1183        1502 :                         insttip = &tinfo;
    1184             :                 }
    1185             :                 else {
    1186      151269 :                         insttip = instanceti;
    1187             :                 }
    1188             : 
    1189             :                 result = resolve_lazy_subtype_checks(refmethod,
    1190             :                                 insttip,
    1191             :                                 to_classref_or_classinfo(container),
    1192      152771 :                                 resolveLinkageError);
    1193      152771 :                 if (result != resolveSucceeded)
    1194         144 :                         return result;
    1195             : 
    1196             :                 /* check protected access */
    1197             : 
    1198      152627 :                 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
    1199             :                 {
    1200             :                         result = resolve_lazy_subtype_checks(refmethod,
    1201             :                                         instanceti,
    1202             :                                         to_classref_or_classinfo(referer),
    1203         172 :                                         resolveIllegalAccessError);
    1204         172 :                         if (result != resolveSucceeded)
    1205           0 :                                 return result;
    1206             :                 }
    1207             : 
    1208             :         }
    1209             : 
    1210             :         /* for PUT* instructions we have to check the constraints on the value type */
    1211             : 
    1212      224379 :         if (valueti) {
    1213       48516 :                 assert(fieldtyperef);
    1214             : 
    1215             :                 /* check subtype constraints */
    1216             :                 result = resolve_lazy_subtype_checks(refmethod,
    1217             :                                 valueti,
    1218             :                                 to_classref_or_classinfo(fieldtyperef),
    1219       48516 :                                 resolveLinkageError);
    1220             : 
    1221       48516 :                 if (result != resolveSucceeded)
    1222        1610 :                         return result;
    1223             :         }
    1224             : 
    1225             :         /* impose loading constraint on field type */
    1226             : 
    1227      222769 :         if (fi->type == TYPE_ADR) {
    1228      149367 :                 assert(fieldtyperef);
    1229      149367 :                 if (!classcache_add_constraint(declarer->classloader,
    1230             :                                                                            referer->classloader,
    1231             :                                                                            fieldtyperef->name))
    1232           0 :                         return resolveFailed;
    1233             :         }
    1234             : 
    1235             :         /* XXX impose loading constraint on instance? */
    1236             : 
    1237             :         /* everything ok */
    1238      222769 :         return resolveSucceeded;
    1239             : }
    1240             : #endif /* defined(ENABLE_VERIFIER) */
    1241             : 
    1242             : /* resolve_field_lazy **********************************************************
    1243             :  
    1244             :    Resolve an unresolved field reference lazily
    1245             : 
    1246             :    NOTE: This function does NOT do any verification checks. In case of a
    1247             :          successful resolution, you must call resolve_field_verifier_checks
    1248             :                  in order to perform the necessary checks!
    1249             :   
    1250             :    IN:
    1251             :            refmethod........the referer method
    1252             :            fieldref.........the field reference
    1253             :   
    1254             :    RETURN VALUE:
    1255             :        resolveSucceeded.....the reference has been resolved
    1256             :        resolveDeferred......the resolving could not be performed lazily
    1257             :            resolveFailed........resolving failed, an exception has been thrown.
    1258             : 
    1259             : *******************************************************************************/
    1260             : 
    1261      225545 : resolve_result_t resolve_field_lazy(methodinfo *refmethod,
    1262             :                                                                         constant_FMIref *fieldref)
    1263             : {
    1264             :         classinfo *referer;
    1265             :         classinfo *container;
    1266             :         fieldinfo *fi;
    1267             : 
    1268      225545 :         assert(refmethod);
    1269             : 
    1270             :         /* the class containing the reference */
    1271             : 
    1272      225545 :         referer = refmethod->clazz;
    1273      225545 :         assert(referer);
    1274             : 
    1275             :         /* check if the field itself is already resolved */
    1276             : 
    1277      225545 :         if (fieldref->is_resolved())
    1278      140766 :                 return resolveSucceeded;
    1279             : 
    1280             :         /* first we must resolve the class containg the field */
    1281             : 
    1282             :         /* XXX can/may lazyResolving trigger linking? */
    1283             : 
    1284       84779 :         if (!resolve_class_from_name(referer, refmethod,
    1285             :                    fieldref->p.classref->name, resolveLazy, true, true, &container))
    1286             :         {
    1287             :                 /* the class reference could not be resolved */
    1288           0 :                 return resolveFailed; /* exception */
    1289             :         }
    1290       84779 :         if (!container)
    1291       19840 :                 return resolveDeferred; /* be lazy */
    1292             : 
    1293       64939 :         assert(container->state & CLASS_LINKED);
    1294             : 
    1295             :         /* now we must find the declaration of the field in `container`
    1296             :          * or one of its superclasses */
    1297             : 
    1298             :         fi = class_resolvefield(container,
    1299             :                                                         fieldref->name, fieldref->descriptor,
    1300       64939 :                                                         referer);
    1301       64939 :         if (!fi) {
    1302             :                 /* The field does not exist. But since we were called lazily, */
    1303             :                 /* this error must not be reported now. (It will be reported   */
    1304             :                 /* if eager resolving of this field is ever tried.)           */
    1305             : 
    1306           2 :                 exceptions_clear_exception();
    1307           2 :                 return resolveDeferred; /* be lazy */
    1308             :         }
    1309             : 
    1310             :         /* cache the result of the resolution */
    1311             : 
    1312       64937 :         fieldref->p.field = fi;
    1313             : 
    1314             :         /* everything ok */
    1315       64937 :         return resolveSucceeded;
    1316             : }
    1317             : 
    1318             : /* resolve_field ***************************************************************
    1319             :  
    1320             :    Resolve an unresolved field reference
    1321             :   
    1322             :    IN:
    1323             :        ref..............struct containing the reference
    1324             :        mode.............mode of resolution:
    1325             :                             resolveLazy...only resolve if it does not
    1326             :                                           require loading classes
    1327             :                             resolveEager..load classes if necessary
    1328             :   
    1329             :    OUT:
    1330             :        *result..........set to the result of resolution, or to NULL if
    1331             :                         the reference has not been resolved
    1332             :                         In the case of an exception, *result is
    1333             :                         guaranteed to be set to NULL.
    1334             :   
    1335             :    RETURN VALUE:
    1336             :        true.............everything ok 
    1337             :                         (*result may still be NULL for resolveLazy)
    1338             :        false............an exception has been thrown
    1339             :    
    1340             : *******************************************************************************/
    1341             : 
    1342       18822 : bool resolve_field(unresolved_field *ref,
    1343             :                                    resolve_mode_t mode,
    1344             :                                    fieldinfo **result)
    1345             : {
    1346             :         classinfo *referer;
    1347             :         classinfo *container;
    1348             :         fieldinfo *fi;
    1349             : 
    1350       18822 :         assert(ref);
    1351       18822 :         assert(result);
    1352       18822 :         assert(mode == resolveLazy || mode == resolveEager);
    1353             : 
    1354       18822 :         *result = NULL;
    1355             : 
    1356             : #ifdef RESOLVE_VERBOSE
    1357             :         unresolved_field_debug_dump(ref,stdout);
    1358             : #endif
    1359             : 
    1360             :         /* the class containing the reference */
    1361             : 
    1362       18822 :         referer = ref->referermethod->clazz;
    1363       18822 :         assert(referer);
    1364             : 
    1365             :         /* check if the field itself is already resolved */
    1366       18822 :         if (ref->fieldref->is_resolved()) {
    1367       16102 :                 fi = ref->fieldref->p.field;
    1368       16102 :                 container = fi->clazz;
    1369       16102 :                 goto resolved_the_field;
    1370             :         }
    1371             : 
    1372             :         /* first we must resolve the class containg the field */
    1373        2720 :         if (!resolve_class_from_name(referer,ref->referermethod,
    1374             :                                            ref->fieldref->p.classref->name,mode,true,true,&container))
    1375             :         {
    1376             :                 /* the class reference could not be resolved */
    1377           0 :                 return false; /* exception */
    1378             :         }
    1379        2720 :         if (!container)
    1380           0 :                 return true; /* be lazy */
    1381             : 
    1382        2720 :         assert(container);
    1383        2720 :         assert(container->state & CLASS_LOADED);
    1384        2720 :         assert(container->state & CLASS_LINKED);
    1385             : 
    1386             :         /* now we must find the declaration of the field in `container`
    1387             :          * or one of its superclasses */
    1388             : 
    1389             : #ifdef RESOLVE_VERBOSE
    1390             :                 printf("    resolving field in class...\n");
    1391             : #endif
    1392             : 
    1393             :         fi = class_resolvefield(container,
    1394             :                                                         ref->fieldref->name,ref->fieldref->descriptor,
    1395        2720 :                                                         referer);
    1396        2720 :         if (!fi) {
    1397           2 :                 if (mode == resolveLazy) {
    1398             :                         /* The field does not exist. But since we were called lazily, */
    1399             :                         /* this error must not be reported now. (It will be reported   */
    1400             :                         /* if eager resolving of this field is ever tried.)           */
    1401             : 
    1402           0 :                         exceptions_clear_exception();
    1403           0 :                         return true; /* be lazy */
    1404             :                 }
    1405             : 
    1406           2 :                 return false; /* exception */
    1407             :         }
    1408             : 
    1409             :         /* cache the result of the resolution */
    1410        2718 :         ref->fieldref->p.field = fi;
    1411             : 
    1412             : resolved_the_field:
    1413             : 
    1414             : #ifdef ENABLE_VERIFIER
    1415             :         /* Checking opt_verify is ok here, because the NULL iptr guarantees */
    1416             :         /* that no missing parts of an instruction will be accessed.        */
    1417       18820 :         if (opt_verify) {
    1418             :                 resolve_result_t checkresult = resolve_field_verifier_checks(
    1419             :                                 ref->referermethod,
    1420             :                                 ref->fieldref,
    1421             :                                 container,
    1422             :                                 fi,
    1423             :                                 NULL, /* instanceti, handled by constraints below */
    1424             :                                 NULL, /* valueti, handled by constraints below  */
    1425             :                                 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
    1426       18820 :                                 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
    1427             : 
    1428       18820 :                 if (checkresult != resolveSucceeded)
    1429           0 :                         return (bool) checkresult;
    1430             : 
    1431       18820 :                 classinfo *declarer = fi->clazz;
    1432       18820 :                 assert(declarer);
    1433       18820 :                 assert(declarer->state & CLASS_LOADED);
    1434       18820 :                 assert(declarer->state & CLASS_LINKED);
    1435             : 
    1436             :                 /* for non-static accesses we have to check the constraints on the */
    1437             :                 /* instance type */
    1438             : 
    1439       18820 :                 if (!(ref->flags & RESOLVE_STATIC)) {
    1440             :                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
    1441             :                                         &(ref->instancetypes),
    1442             :                                         to_classref_or_classinfo(container),
    1443         650 :                                         mode, resolveLinkageError);
    1444         650 :                         if (checkresult != resolveSucceeded)
    1445           0 :                                 return (bool) checkresult;
    1446             :                 }
    1447             : 
    1448       18820 :                 constant_classref *fieldtyperef = ref->fieldref->parseddesc.fd->classref;
    1449             : 
    1450             :                 /* for PUT* instructions we have to check the constraints on the value type */
    1451       18820 :                 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
    1452        1587 :                         assert(fieldtyperef);
    1453        1587 :                         if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
    1454             :                                 /* check subtype constraints */
    1455             :                                 checkresult = resolve_and_check_subtype_set(ref->referermethod,
    1456             :                                                 &(ref->valueconstraints),
    1457             :                                                 to_classref_or_classinfo(fieldtyperef),
    1458        1561 :                                                 mode, resolveLinkageError);
    1459        1561 :                                 if (checkresult != resolveSucceeded)
    1460           0 :                                         return (bool) checkresult;
    1461             :                         }
    1462             :                 }
    1463             : 
    1464             :                 /* check protected access */
    1465       18820 :                 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
    1466             :                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
    1467             :                                         &(ref->instancetypes),
    1468             :                                         to_classref_or_classinfo(referer),
    1469             :                                         mode,
    1470           0 :                                         resolveIllegalAccessError);
    1471           0 :                         if (checkresult != resolveSucceeded)
    1472           0 :                                 return (bool) checkresult;
    1473             :                 }
    1474             : 
    1475             :         }
    1476             : #endif /* ENABLE_VERIFIER */
    1477             : 
    1478             :         /* succeed */
    1479       18820 :         *result = fi;
    1480             : 
    1481       18820 :         return true;
    1482             : }
    1483             : 
    1484             : /* resolve_field_eager *********************************************************
    1485             :  
    1486             :    Resolve an unresolved field reference eagerly.
    1487             :   
    1488             :    IN:
    1489             :        ref..............struct containing the reference
    1490             :    
    1491             :    RETURN VALUE:
    1492             :        fieldinfo * to the field, or
    1493             :            NULL if an exception has been thrown
    1494             :    
    1495             : *******************************************************************************/
    1496             : 
    1497       18822 : fieldinfo * resolve_field_eager(unresolved_field *ref)
    1498             : {
    1499             :         fieldinfo *fi;
    1500             : 
    1501       18822 :         if (!resolve_field(ref,resolveEager,&fi))
    1502           2 :                 return NULL;
    1503             : 
    1504       18820 :         return fi;
    1505             : }
    1506             : 
    1507             : /******************************************************************************/
    1508             : /* METHOD RESOLUTION                                                          */
    1509             : /******************************************************************************/
    1510             : 
    1511             : /* resolve_method_invokespecial_lookup *****************************************
    1512             :  
    1513             :    Do the special lookup for methods invoked by INVOKESPECIAL
    1514             :   
    1515             :    IN:
    1516             :        refmethod........the method containing the reference
    1517             :            mi...............the methodinfo of the resolved method
    1518             :   
    1519             :    RETURN VALUE:
    1520             :        a methodinfo *...the result of the lookup,
    1521             :            NULL.............an exception has been thrown
    1522             :    
    1523             : *******************************************************************************/
    1524             : 
    1525       53296 : methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
    1526             :                                                                                                  methodinfo *mi)
    1527             : {
    1528             :         classinfo *declarer;
    1529             :         classinfo *referer;
    1530             : 
    1531       53296 :         assert(refmethod);
    1532       53296 :         assert(mi);
    1533             : 
    1534             :         /* get referer and declarer classes */
    1535             : 
    1536       53296 :         referer = refmethod->clazz;
    1537       53296 :         assert(referer);
    1538             : 
    1539       53296 :         declarer = mi->clazz;
    1540       53296 :         assert(declarer);
    1541       53296 :         assert(referer->state & CLASS_LINKED);
    1542             : 
    1543             :         /* checks for INVOKESPECIAL:                                       */
    1544             :         /* for <init> and methods of the current class we don't need any   */
    1545             :         /* special checks. Otherwise we must verify that the called method */
    1546             :         /* belongs to a super class of the current class                   */
    1547             : 
    1548       53296 :         if ((referer != declarer) && (mi->name != utf8::init)) {
    1549             :                 /* check that declarer is a super class of the current class   */
    1550             : 
    1551        1255 :                 if (!class_issubclass(referer,declarer)) {
    1552             :                         exceptions_throw_verifyerror(refmethod,
    1553           0 :                                         "INVOKESPECIAL calling non-super class method");
    1554           0 :                         return NULL;
    1555             :                 }
    1556             : 
    1557             :                 /* if the referer has ACC_SUPER set, we must do the special    */
    1558             :                 /* lookup starting with the direct super class of referer      */
    1559             : 
    1560        1255 :                 if ((referer->flags & ACC_SUPER) != 0) {
    1561             :                         mi = class_resolvemethod(referer->super,
    1562             :                                                                          mi->name,
    1563        1255 :                                                                          mi->descriptor);
    1564             : 
    1565        1255 :                         if (mi == NULL) {
    1566             :                                 /* the spec calls for an AbstractMethodError in this case */
    1567             : 
    1568           0 :                                 exceptions_throw_abstractmethoderror();
    1569             : 
    1570           0 :                                 return NULL;
    1571             :                         }
    1572             :                 }
    1573             :         }
    1574             : 
    1575             :         /* everything ok */
    1576       53296 :         return mi;
    1577             : }
    1578             : 
    1579             : /* resolve_method_verifier_checks ******************************************
    1580             :  
    1581             :    Do the verifier checks necessary after a method has been resolved.
    1582             :   
    1583             :    IN:
    1584             :        refmethod........the method containing the reference
    1585             :            methodref........the method reference
    1586             :            mi...............the methodinfo of the resolved method
    1587             :            invokestatic.....true if the method is invoked by INVOKESTATIC
    1588             :   
    1589             :    RETURN VALUE:
    1590             :        resolveSucceeded....everything ok
    1591             :            resolveDeferred.....tests could not be done, have been deferred
    1592             :        resolveFailed.......exception has been thrown
    1593             :    
    1594             : *******************************************************************************/
    1595             : 
    1596             : #if defined(ENABLE_VERIFIER)
    1597      265894 : resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
    1598             :                                                                                                 constant_FMIref *methodref,
    1599             :                                                                                                 methodinfo *mi,
    1600             :                                                                                                 bool invokestatic)
    1601             : {
    1602             :         classinfo *declarer;
    1603             :         classinfo *referer;
    1604             : 
    1605      265894 :         assert(refmethod);
    1606      265894 :         assert(methodref);
    1607      265894 :         assert(mi);
    1608             : 
    1609             : #ifdef RESOLVE_VERBOSE
    1610             :         printf("resolve_method_verifier_checks\n");
    1611             :         printf("    flags: %02x\n",mi->flags);
    1612             : #endif
    1613             : 
    1614             :         /* get the classinfos and the method descriptor */
    1615             : 
    1616      265894 :         referer = refmethod->clazz;
    1617      265894 :         assert(referer);
    1618             : 
    1619      265894 :         declarer = mi->clazz;
    1620      265894 :         assert(declarer);
    1621             : 
    1622             :         /* check static */
    1623             : 
    1624      265894 :         if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
    1625             :                 /* a static method is accessed via an instance, or vice versa */
    1626             :                 exceptions_throw_incompatibleclasschangeerror(declarer,
    1627             :                                                                                                           (mi->flags & ACC_STATIC)
    1628             :                                                                                                           ? "static method called via instance"
    1629           0 :                                                                                                           : "instance method called without instance");
    1630             : 
    1631           0 :                 return resolveFailed;
    1632             :         }
    1633             : 
    1634             :         /* check access rights */
    1635             : 
    1636      265894 :         if (!access_is_accessible_member(referer,declarer,mi->flags)) {
    1637             :                 /* XXX clean this up. this should be in exceptions.c */
    1638             : 
    1639           0 :                 Buffer<> buf(64);
    1640             : 
    1641             :                 Utf8String u = buf.write("method is not accessible (")
    1642             :                                   .write_slash_to_dot(declarer->name)
    1643             :                                   .write(".")
    1644             :                                   .write(mi->name)
    1645             :                                   .write(mi->descriptor)
    1646             :                                   .write(" from ")
    1647             :                                   .write_slash_to_dot(referer->name)
    1648             :                                   .write(")")
    1649           0 :                                   .utf8_str();
    1650             : 
    1651           0 :                 exceptions_throw_illegalaccessexception(u);
    1652           0 :                 return resolveFailed; /* exception */
    1653             :         }
    1654             : 
    1655             :         /* everything ok */
    1656             : 
    1657      265894 :         return resolveSucceeded;
    1658             : }
    1659             : #endif /* defined(ENABLE_VERIFIER) */
    1660             : 
    1661             : 
    1662             : /* resolve_method_instance_type_checks *****************************************
    1663             : 
    1664             :    Check the instance type of a method invocation.
    1665             : 
    1666             :    IN:
    1667             :        refmethod........the method containing the reference
    1668             :            mi...............the methodinfo of the resolved method
    1669             :            instanceti.......typeinfo of the instance slot
    1670             :            invokespecial....true if the method is invoked by INVOKESPECIAL
    1671             : 
    1672             :    RETURN VALUE:
    1673             :        resolveSucceeded....everything ok
    1674             :            resolveDeferred.....tests could not be done, have been deferred
    1675             :        resolveFailed.......exception has been thrown
    1676             : 
    1677             : *******************************************************************************/
    1678             : 
    1679             : #if defined(ENABLE_VERIFIER)
    1680      181750 : resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
    1681             :                                                                                                          methodinfo *mi,
    1682             :                                                                                                          typeinfo_t *instanceti,
    1683             :                                                                                                          bool invokespecial)
    1684             : {
    1685             :         typeinfo_t         tinfo;
    1686             :         typeinfo_t        *tip;
    1687             :         resolve_result_t result;
    1688             : 
    1689      181750 :         if (invokespecial && instanceti->is_newobject())
    1690             :         {   /* XXX clean up */
    1691           0 :                 instruction *ins = instanceti->newobject_instruction();
    1692           0 :                 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c : to_classref_or_classinfo(refmethod->clazz);
    1693           0 :                 tip = &tinfo;
    1694           0 :                 if (!tip->init_class(initclass))
    1695           0 :                         return resolveFailed;
    1696             :         }
    1697             :         else {
    1698      181750 :                 tip = instanceti;
    1699             :         }
    1700             : 
    1701             :         result = resolve_lazy_subtype_checks(refmethod,
    1702             :                                                                                  tip,
    1703             :                                                                                  to_classref_or_classinfo(mi->clazz),
    1704      181750 :                                                                                  resolveLinkageError);
    1705      181750 :         if (result != resolveSucceeded)
    1706         154 :                 return result;
    1707             : 
    1708             :         /* check protected access */
    1709             : 
    1710             :         /* XXX use other `declarer` than mi->clazz? */
    1711      181596 :         if (((mi->flags & ACC_PROTECTED) != 0)
    1712             :                         && !SAME_PACKAGE(mi->clazz, refmethod->clazz))
    1713             :         {
    1714             :                 result = resolve_lazy_subtype_checks(refmethod,
    1715             :                                 tip,
    1716             :                                 to_classref_or_classinfo(refmethod->clazz),
    1717        3833 :                                 resolveIllegalAccessError);
    1718        3833 :                 if (result != resolveSucceeded)
    1719           0 :                         return result;
    1720             :         }
    1721             : 
    1722             :         /* everything ok */
    1723             : 
    1724      181596 :         return resolveSucceeded;
    1725             : }
    1726             : #endif /* defined(ENABLE_VERIFIER) */
    1727             : 
    1728             : 
    1729             : /* resolve_method_param_type_checks ********************************************
    1730             : 
    1731             :    Check non-instance parameter types of a method invocation.
    1732             : 
    1733             :    IN:
    1734             :            jd...............jitdata of the method doing the call
    1735             :        refmethod........the method containing the reference
    1736             :            iptr.............the invoke instruction
    1737             :            mi...............the methodinfo of the resolved method
    1738             :            invokestatic.....true if the method is invoked by INVOKESTATIC
    1739             : 
    1740             :    RETURN VALUE:
    1741             :        resolveSucceeded....everything ok
    1742             :            resolveDeferred.....tests could not be done, have been deferred
    1743             :        resolveFailed.......exception has been thrown
    1744             : 
    1745             : *******************************************************************************/
    1746             : 
    1747             : #if defined(ENABLE_VERIFIER)
    1748      232413 : resolve_result_t resolve_method_param_type_checks(jitdata *jd, 
    1749             :                                                                                                   methodinfo *refmethod,
    1750             :                                                                                                   instruction *iptr, 
    1751             :                                                                                                   methodinfo *mi,
    1752             :                                                                                                   bool invokestatic)
    1753             : {
    1754             :         varinfo         *param;
    1755             :         resolve_result_t result;
    1756             :         methoddesc      *md;
    1757             :         typedesc        *paramtypes;
    1758             :         s4               type;
    1759             :         s4               instancecount;
    1760             :         s4               i;
    1761             : 
    1762      232413 :         assert(jd);
    1763             : 
    1764      232413 :         instancecount = (invokestatic) ? 0 : 1;
    1765             : 
    1766             :         /* check subtype constraints for TYPE_ADR parameters */
    1767             : 
    1768      232413 :         md = mi->parseddesc;
    1769      232413 :         paramtypes = md->paramtypes;
    1770             : 
    1771      443926 :         for (i = md->paramcount-1-instancecount; i>=0; --i) {
    1772      220725 :                 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
    1773      220725 :                 type = md->paramtypes[i+instancecount].type;
    1774             : 
    1775      220725 :                 assert(param);
    1776      220725 :                 assert(type == param->type);
    1777             : 
    1778      220725 :                 if (type == TYPE_ADR) {
    1779             :                         result = resolve_lazy_subtype_checks(refmethod,
    1780             :                                         &(param->typeinfo),
    1781      148525 :                                         to_classref_or_classinfo(paramtypes[i+instancecount].classref),
    1782      148525 :                                         resolveLinkageError);
    1783      148525 :                         if (result != resolveSucceeded)
    1784        9212 :                                 return result;
    1785             :                 }
    1786             :         }
    1787             : 
    1788             :         /* everything ok */
    1789             : 
    1790      223201 :         return resolveSucceeded;
    1791             : }
    1792             : #endif /* defined(ENABLE_VERIFIER) */
    1793             : 
    1794             : 
    1795             : /* resolve_method_param_type_checks_stackbased *********************************
    1796             : 
    1797             :    Check non-instance parameter types of a method invocation.
    1798             : 
    1799             :    IN:
    1800             :        refmethod........the method containing the reference
    1801             :            mi...............the methodinfo of the resolved method
    1802             :            invokestatic.....true if the method is invoked by INVOKESTATIC
    1803             :            stack............TOS before the INVOKE instruction
    1804             : 
    1805             :    RETURN VALUE:
    1806             :        resolveSucceeded....everything ok
    1807             :            resolveDeferred.....tests could not be done, have been deferred
    1808             :        resolveFailed.......exception has been thrown
    1809             : 
    1810             : *******************************************************************************/
    1811             : 
    1812             : #if defined(ENABLE_VERIFIER)
    1813           0 : resolve_result_t resolve_method_param_type_checks_stackbased(
    1814             :                 methodinfo *refmethod, 
    1815             :                 methodinfo *mi,
    1816             :                 bool invokestatic, 
    1817             :                 typedescriptor_t *stack)
    1818             : {
    1819             :         typedescriptor_t  *param;
    1820             :         resolve_result_t result;
    1821             :         methoddesc      *md;
    1822             :         typedesc        *paramtypes;
    1823             :         s4               type;
    1824             :         s4               instancecount;
    1825             :         s4               i;
    1826             : 
    1827           0 :         instancecount = (invokestatic) ? 0 : 1;
    1828             : 
    1829             :         /* check subtype constraints for TYPE_ADR parameters */
    1830             : 
    1831           0 :         md = mi->parseddesc;
    1832           0 :         paramtypes = md->paramtypes;
    1833             : 
    1834           0 :         param = stack - (md->paramslots - 1 - instancecount);
    1835             : 
    1836           0 :         for (i = instancecount; i < md->paramcount; ++i) {
    1837           0 :                 type = md->paramtypes[i].type;
    1838             : 
    1839           0 :                 assert(type == param->type);
    1840             : 
    1841           0 :                 if (type == TYPE_ADR) {
    1842             :                         result = resolve_lazy_subtype_checks(refmethod,
    1843             :                                         &(param->typeinfo),
    1844           0 :                                         to_classref_or_classinfo(paramtypes[i].classref),
    1845           0 :                                         resolveLinkageError);
    1846           0 :                         if (result != resolveSucceeded)
    1847           0 :                                 return result;
    1848             :                 }
    1849             : 
    1850           0 :                 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
    1851             :         }
    1852             : 
    1853             :         /* everything ok */
    1854             : 
    1855           0 :         return resolveSucceeded;
    1856             : }
    1857             : #endif /* defined(ENABLE_VERIFIER) */
    1858             : 
    1859             : 
    1860             : /* resolve_method_loading_constraints ******************************************
    1861             : 
    1862             :    Impose loading constraints on the parameters and return type of the
    1863             :    given method.
    1864             : 
    1865             :    IN:
    1866             :        referer..........the class refering to the method
    1867             :            mi...............the method
    1868             : 
    1869             :    RETURN VALUE:
    1870             :        true................everything ok
    1871             :            false...............an exception has been thrown
    1872             : 
    1873             : *******************************************************************************/
    1874             : 
    1875             : #if defined(ENABLE_VERIFIER)
    1876      256528 : bool resolve_method_loading_constraints(classinfo *referer,
    1877             :                                                                                 methodinfo *mi)
    1878             : {
    1879             :         methoddesc *md;
    1880             :         typedesc   *paramtypes;
    1881      256528 :         Utf8String  name;
    1882             :         s4          i;
    1883             :         s4          instancecount;
    1884             : 
    1885             :         /* impose loading constraints on parameters (including instance) */
    1886             : 
    1887      256528 :         md = mi->parseddesc;
    1888      256528 :         paramtypes = md->paramtypes;
    1889      256528 :         instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
    1890             : 
    1891      699148 :         for (i = 0; i < md->paramcount; i++) {
    1892      442620 :                 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
    1893      371394 :                         if (i < instancecount) {
    1894             :                                 /* The type of the 'this' pointer is the class containing */
    1895             :                                 /* the method definition. Since container is the same as, */
    1896             :                                 /* or a subclass of declarer, we also constrain declarer  */
    1897             :                                 /* by transitivity of loading constraints.                */
    1898       47635 :                                 name = mi->clazz->name;
    1899             :                         }
    1900             :                         else {
    1901      323759 :                                 name = paramtypes[i].classref->name;
    1902             :                         }
    1903             : 
    1904             :                         /* The caller (referer) and the callee (container) must agree */
    1905             :                         /* on the types of the parameters.                            */
    1906      371394 :                         if (!classcache_add_constraint(referer->classloader,
    1907             :                                                                                    mi->clazz->classloader, name))
    1908           0 :                                 return false; /* exception */
    1909             :                 }
    1910             :         }
    1911             : 
    1912             :         /* impose loading constraint onto return type */
    1913             : 
    1914      256528 :         if (md->returntype.type == TYPE_ADR) {
    1915             :                 /* The caller (referer) and the callee (container) must agree */
    1916             :                 /* on the return type.                                        */
    1917      117718 :                 if (!classcache_add_constraint(referer->classloader,
    1918             :                                         mi->clazz->classloader,
    1919             :                                         md->returntype.classref->name))
    1920           0 :                         return false; /* exception */
    1921             :         }
    1922             : 
    1923             :         /* everything ok */
    1924             : 
    1925      256528 :         return true;
    1926             : }
    1927             : #endif /* defined(ENABLE_VERIFIER) */
    1928             : 
    1929             : 
    1930             : /* resolve_method_lazy *********************************************************
    1931             :  
    1932             :    Resolve an unresolved method reference lazily
    1933             :   
    1934             :    NOTE: This function does NOT do any verification checks. In case of a
    1935             :          successful resolution, you must call resolve_method_verifier_checks
    1936             :                  in order to perform the necessary checks!
    1937             :   
    1938             :    IN:
    1939             :            refmethod........the referer method
    1940             :            methodref........the method reference
    1941             :            invokespecial....true if this is an INVOKESPECIAL instruction
    1942             :   
    1943             :    RETURN VALUE:
    1944             :        resolveSucceeded.....the reference has been resolved
    1945             :        resolveDeferred......the resolving could not be performed lazily
    1946             :            resolveFailed........resolving failed, an exception has been thrown.
    1947             :    
    1948             : *******************************************************************************/
    1949             : 
    1950      289988 : resolve_result_t resolve_method_lazy(methodinfo *refmethod,
    1951             :                                                                          constant_FMIref *methodref,
    1952             :                                                                          bool invokespecial)
    1953             : {
    1954             :         classinfo *referer;
    1955             :         classinfo *container;
    1956             :         methodinfo *mi;
    1957             : 
    1958      289988 :         assert(refmethod);
    1959             : 
    1960             : #ifdef RESOLVE_VERBOSE
    1961             :         printf("resolve_method_lazy\n");
    1962             : #endif
    1963             : 
    1964             :         /* the class containing the reference */
    1965             : 
    1966      289988 :         referer = refmethod->clazz;
    1967      289988 :         assert(referer);
    1968             : 
    1969             :         /* check if the method itself is already resolved */
    1970             : 
    1971      289988 :         if (methodref->is_resolved())
    1972      104754 :                 return resolveSucceeded;
    1973             : 
    1974             :         /* first we must resolve the class containg the method */
    1975             : 
    1976      185234 :         if (!resolve_class_from_name(referer, refmethod,
    1977             :                    methodref->p.classref->name, resolveLazy, true, true, &container))
    1978             :         {
    1979             :                 /* the class reference could not be resolved */
    1980           0 :                 return resolveFailed; /* exception */
    1981             :         }
    1982      185234 :         if (!container)
    1983       57421 :                 return resolveDeferred; /* be lazy */
    1984             : 
    1985      127813 :         assert(container->state & CLASS_LINKED);
    1986             : 
    1987             :         /* now we must find the declaration of the method in `container`
    1988             :          * or one of its superclasses */
    1989             : 
    1990      127813 :         if (container->flags & ACC_INTERFACE) {
    1991             :                 mi = class_resolveinterfacemethod(container,
    1992             :                                                                               methodref->name,
    1993             :                                                                                   methodref->descriptor,
    1994        5167 :                                                                               referer, true);
    1995             : 
    1996             :         } else {
    1997             :                 mi = class_resolveclassmethod(container,
    1998             :                                                                           methodref->name,
    1999             :                                                                           methodref->descriptor,
    2000      122646 :                                                                           referer, true);
    2001             :         }
    2002             : 
    2003      127813 :         if (!mi) {
    2004             :                 /* The method does not exist. But since we were called lazily, */
    2005             :                 /* this error must not be reported now. (It will be reported   */
    2006             :                 /* if eager resolving of this method is ever tried.)           */
    2007             : 
    2008           0 :                 exceptions_clear_exception();
    2009           0 :                 return resolveDeferred; /* be lazy */
    2010             :         }
    2011             : 
    2012      127813 :         if (invokespecial) {
    2013       41074 :                 mi = resolve_method_invokespecial_lookup(refmethod, mi);
    2014       41074 :                 if (!mi)
    2015           0 :                         return resolveFailed; /* exception */
    2016             :         }
    2017             : 
    2018             :         /* have the method params already been parsed? no, do it. */
    2019             : 
    2020      127813 :         mi->parseddesc->params_from_paramtypes(mi->flags);
    2021             : 
    2022             :         /* cache the result of the resolution */
    2023             : 
    2024      127813 :         methodref->p.method = mi;
    2025             : 
    2026             :         /* succeed */
    2027             : 
    2028      127813 :         return resolveSucceeded;
    2029             : }
    2030             : 
    2031             : /* resolve_method **************************************************************
    2032             : 
    2033             :    Resolve an unresolved method reference
    2034             : 
    2035             :    IN:
    2036             :        ref..............struct containing the reference
    2037             :        mode.............mode of resolution:
    2038             :                             resolveLazy...only resolve if it does not
    2039             :                                           require loading classes
    2040             :                             resolveEager..load classes if necessary
    2041             : 
    2042             :    OUT:
    2043             :        *result..........set to the result of resolution, or to NULL if
    2044             :                         the reference has not been resolved
    2045             :                         In the case of an exception, *result is
    2046             :                         guaranteed to be set to NULL.
    2047             : 
    2048             :    RETURN VALUE:
    2049             :        true.............everything ok
    2050             :                         (*result may still be NULL for resolveLazy)
    2051             :        false............an exception has been thrown
    2052             : 
    2053             : *******************************************************************************/
    2054             : 
    2055       33330 : bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
    2056             : {
    2057             :         classinfo *referer;
    2058             :         classinfo *container;
    2059             :         methodinfo *mi;
    2060             : 
    2061       33330 :         assert(ref);
    2062       33330 :         assert(result);
    2063       33330 :         assert(mode == resolveLazy || mode == resolveEager);
    2064             : 
    2065             : #ifdef RESOLVE_VERBOSE
    2066             :         unresolved_method_debug_dump(ref,stdout);
    2067             : #endif
    2068             : 
    2069       33330 :         *result = NULL;
    2070             : 
    2071             :         /* the class containing the reference */
    2072             : 
    2073       33330 :         referer = ref->referermethod->clazz;
    2074       33330 :         assert(referer);
    2075             : 
    2076             :         /* check if the method itself is already resolved */
    2077             : 
    2078       33330 :         if (ref->methodref->is_resolved()) {
    2079       11212 :                 mi = ref->methodref->p.method;
    2080       11212 :                 container = mi->clazz;
    2081       11212 :                 goto resolved_the_method;
    2082             :         }
    2083             : 
    2084             :         /* first we must resolve the class containing the method */
    2085             : 
    2086       22118 :         if (!resolve_class_from_name(referer,ref->referermethod,
    2087             :                                            ref->methodref->p.classref->name,mode,true,true,&container))
    2088             :         {
    2089             :                 /* the class reference could not be resolved */
    2090           3 :                 return false; /* exception */
    2091             :         }
    2092       22115 :         if (!container)
    2093           0 :                 return true; /* be lazy */
    2094             : 
    2095       22115 :         assert(container);
    2096       22115 :         assert(container->state & CLASS_LINKED);
    2097             : 
    2098             :         /* now we must find the declaration of the method in `container`
    2099             :          * or one of its superclasses */
    2100             : 
    2101       22115 :         if (container->flags & ACC_INTERFACE) {
    2102             :                 mi = class_resolveinterfacemethod(container,
    2103             :                                                                               ref->methodref->name,
    2104             :                                                                                   ref->methodref->descriptor,
    2105         458 :                                                                               referer, true);
    2106             : 
    2107             :         } else {
    2108             :                 mi = class_resolveclassmethod(container,
    2109             :                                                                           ref->methodref->name,
    2110             :                                                                           ref->methodref->descriptor,
    2111       21657 :                                                                           referer, true);
    2112             :         }
    2113             : 
    2114       22115 :         if (!mi) {
    2115           0 :                 if (mode == resolveLazy) {
    2116             :                         /* The method does not exist. But since we were called lazily, */
    2117             :                         /* this error must not be reported now. (It will be reported   */
    2118             :                         /* if eager resolving of this method is ever tried.)           */
    2119             : 
    2120           0 :                         exceptions_clear_exception();
    2121           0 :                         return true; /* be lazy */
    2122             :                 }
    2123             : 
    2124           0 :                 return false; /* exception */ /* XXX set exceptionptr? */
    2125             :         }
    2126             : 
    2127             :         /* { the method reference has been resolved } */
    2128             : 
    2129       22115 :         if (ref->flags & RESOLVE_SPECIAL) {
    2130       12222 :                 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
    2131       12222 :                 if (!mi)
    2132           0 :                         return false; /* exception */
    2133             :         }
    2134             : 
    2135             :         /* have the method params already been parsed? no, do it. */
    2136             : 
    2137       22115 :         mi->parseddesc->params_from_paramtypes(mi->flags);
    2138             : 
    2139             :         /* cache the resolution */
    2140             : 
    2141       22115 :         ref->methodref->p.method = mi;
    2142             : 
    2143             : resolved_the_method:
    2144             : 
    2145             : #ifdef ENABLE_VERIFIER
    2146       33327 :         if (opt_verify) {
    2147             :                 resolve_result_t checkresult = resolve_method_verifier_checks(
    2148             :                                 ref->referermethod,
    2149             :                                 ref->methodref,
    2150             :                                 mi,
    2151       33327 :                                 (ref->flags & RESOLVE_STATIC));
    2152             : 
    2153       33327 :                 if (checkresult != resolveSucceeded)
    2154           0 :                         return (bool) checkresult;
    2155             : 
    2156             :                 /* impose loading constraints on params and return type */
    2157             : 
    2158       33327 :                 if (!resolve_method_loading_constraints(referer, mi))
    2159           0 :                         return false;
    2160             : 
    2161       33327 :                 classinfo *declarer = mi->clazz;
    2162       33327 :                 assert(declarer);
    2163       33327 :                 assert(referer->state & CLASS_LINKED);
    2164             : 
    2165             :                 /* for non-static methods we have to check the constraints on the         */
    2166             :                 /* instance type                                                          */
    2167             : 
    2168             :                 int instancecount;
    2169             : 
    2170       33327 :                 if (!(ref->flags & RESOLVE_STATIC)) {
    2171             :                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
    2172             :                                         &(ref->instancetypes),
    2173             :                                         to_classref_or_classinfo(container),
    2174             :                                         mode,
    2175       27593 :                                         resolveLinkageError);
    2176       27593 :                         if (checkresult != resolveSucceeded)
    2177           1 :                                 return (bool) checkresult;
    2178       27592 :                         instancecount = 1;
    2179             :                 }
    2180             :                 else {
    2181        5734 :                         instancecount = 0;
    2182             :                 }
    2183             : 
    2184             :                 /* check subtype constraints for TYPE_ADR parameters */
    2185             : 
    2186       33326 :                 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
    2187       33326 :                 typedesc *paramtypes = mi->parseddesc->paramtypes;
    2188             : 
    2189       64370 :                 for (int i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
    2190       31045 :                         if (paramtypes[i+instancecount].type == TYPE_ADR) {
    2191       26255 :                                 if (ref->paramconstraints) {
    2192             :                                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
    2193             :                                                         ref->paramconstraints + i,
    2194       26255 :                                                         to_classref_or_classinfo(paramtypes[i+instancecount].classref),
    2195             :                                                         mode,
    2196       26255 :                                                         resolveLinkageError);
    2197       26255 :                                         if (checkresult != resolveSucceeded)
    2198           1 :                                                 return (bool) checkresult;
    2199             :                                 }
    2200             :                         }
    2201             :                 }
    2202             : 
    2203             :                 /* check protected access */
    2204             : 
    2205       33325 :                 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
    2206             :                 {
    2207             :                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
    2208             :                                         &(ref->instancetypes),
    2209             :                                         to_classref_or_classinfo(referer),
    2210             :                                         mode,
    2211           0 :                                         resolveIllegalAccessError);
    2212           0 :                         if (checkresult != resolveSucceeded)
    2213           0 :                                 return (bool) checkresult;
    2214             :                 }
    2215             :         }
    2216             : #endif /* ENABLE_VERIFIER */
    2217             : 
    2218             :         /* succeed */
    2219       33325 :         *result = mi;
    2220       33325 :         return true;
    2221             : }
    2222             : 
    2223             : /* resolve_method_eager ********************************************************
    2224             :  
    2225             :    Resolve an unresolved method reference eagerly.
    2226             :   
    2227             :    IN:
    2228             :        ref..............struct containing the reference
    2229             :    
    2230             :    RETURN VALUE:
    2231             :        methodinfo * to the method, or
    2232             :            NULL if an exception has been thrown
    2233             :    
    2234             : *******************************************************************************/
    2235             : 
    2236       33330 : methodinfo * resolve_method_eager(unresolved_method *ref)
    2237             : {
    2238             :         methodinfo *mi;
    2239             : 
    2240       33330 :         if (!resolve_method(ref,resolveEager,&mi))
    2241           5 :                 return NULL;
    2242             : 
    2243       33325 :         return mi;
    2244             : }
    2245             : 
    2246             : /******************************************************************************/
    2247             : /* CREATING THE DATA STRUCTURES                                               */
    2248             : /******************************************************************************/
    2249             : 
    2250             : #ifdef ENABLE_VERIFIER
    2251      131701 : static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
    2252             :                                                                                                  methodinfo *refmethod,
    2253             :                                                                                                  unresolved_subtype_set *stset,
    2254             :                                                                                                  typeinfo_t *tinfo,
    2255             :                                                                                                  Utf8String declaredclassname)
    2256             : {
    2257             :         int count;
    2258             :         int i;
    2259             : 
    2260      131701 :         assert(stset);
    2261      131701 :         assert(tinfo);
    2262             : 
    2263             : #ifdef RESOLVE_VERBOSE
    2264             :         printf("unresolved_subtype_set_from_typeinfo\n");
    2265             : #ifdef TYPEINFO_DEBUG
    2266             :         typeinfo_print(stdout,tinfo,4);
    2267             : #endif
    2268             :         printf("    declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
    2269             :         printf("\n");
    2270             : #endif
    2271             : 
    2272      131701 :         if (tinfo->is_primitive()) {
    2273             :                 exceptions_throw_verifyerror(refmethod,
    2274           0 :                                 "Invalid use of returnAddress");
    2275           0 :                 return false;
    2276             :         }
    2277             : 
    2278      131701 :         if (tinfo->is_newobject()) {
    2279             :                 exceptions_throw_verifyerror(refmethod,
    2280           0 :                                 "Invalid use of uninitialized object");
    2281           0 :                 return false;
    2282             :         }
    2283             : 
    2284             :         /* the nulltype is always assignable */
    2285      131701 :         if (tinfo->is_nulltype())
    2286        2774 :                 goto empty_set;
    2287             : 
    2288             :         /* every type is assignable to (BOOTSTRAP)java.lang.Object */
    2289      128927 :         if (declaredclassname == utf8::java_lang_Object
    2290             :                         && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
    2291             :         {
    2292        4487 :                 goto empty_set;
    2293             :         }
    2294             : 
    2295      124440 :         if (tinfo->merged) {
    2296         715 :                 count = tinfo->merged->count;
    2297         715 :                 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
    2298        5088 :                 for (i=0; i<count; ++i) {
    2299        4373 :                         classref_or_classinfo c = tinfo->merged->list[i];
    2300        4373 :                         if (tinfo->dimension > 0) {
    2301             :                                 /* a merge of array types */
    2302             :                                 /* the merged list contains the possible _element_ types, */
    2303             :                                 /* so we have to create array types with these elements.  */
    2304           0 :                                 if (c.is_classref()) {
    2305           0 :                                         c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
    2306             :                                 }
    2307             :                                 else {
    2308           0 :                                         c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
    2309             :                                 }
    2310             :                         }
    2311        4373 :                         stset->subtyperefs[i] = c;
    2312             :                 }
    2313         715 :                 stset->subtyperefs[count].any = NULL; /* terminate */
    2314             :         }
    2315             :         else {
    2316      123725 :                 if (CLASSREF_OR_CLASSINFO_NAME(tinfo->typeclass) == declaredclassname)
    2317             :                 {
    2318             :                         /* the class names are the same */
    2319             :                     /* equality is guaranteed by the loading constraints */
    2320       88902 :                         goto empty_set;
    2321             :                 }
    2322             :                 else {
    2323       34823 :                         stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
    2324       34823 :                         stset->subtyperefs[0] = tinfo->typeclass;
    2325       34823 :                         stset->subtyperefs[1].any = NULL; /* terminate */
    2326             :                 }
    2327             :         }
    2328             : 
    2329       35538 :         return true;
    2330             : 
    2331             : empty_set:
    2332       96163 :         UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
    2333       96163 :         return true;
    2334             : }
    2335             : #endif /* ENABLE_VERIFIER */
    2336             : 
    2337             : /* create_unresolved_class *****************************************************
    2338             :  
    2339             :    Create an unresolved_class struct for the given class reference
    2340             :   
    2341             :    IN:
    2342             :            refmethod........the method triggering the resolution (if any)
    2343             :            classref.........the class reference
    2344             :            valuetype........value type to check against the resolved class
    2345             :                                                 may be NULL, if no typeinfo is available
    2346             : 
    2347             :    RETURN VALUE:
    2348             :        a pointer to a new unresolved_class struct, or
    2349             :            NULL if an exception has been thrown
    2350             : 
    2351             : *******************************************************************************/
    2352             : 
    2353             : #ifdef ENABLE_VERIFIER
    2354       18633 : unresolved_class * create_unresolved_class(methodinfo *refmethod,
    2355             :                                                                                    constant_classref *classref,
    2356             :                                                                                    typeinfo_t *valuetype)
    2357             : {
    2358             :         unresolved_class *ref;
    2359             : 
    2360             : #ifdef RESOLVE_VERBOSE
    2361             :         printf("create_unresolved_class\n");
    2362             :         printf("    referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
    2363             :         if (refmethod) {
    2364             :                 printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
    2365             :                 printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
    2366             :         }
    2367             :         printf("    name   : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
    2368             : #endif
    2369             : 
    2370       18633 :         ref = NEW(unresolved_class);
    2371       18633 :         ref->classref = classref;
    2372       18633 :         ref->referermethod = refmethod;
    2373             : 
    2374       18633 :         if (valuetype) {
    2375       18633 :                 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
    2376             :                                         &(ref->subtypeconstraints),valuetype,classref->name))
    2377           0 :                         return NULL;
    2378             :         }
    2379             :         else {
    2380           0 :                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
    2381             :         }
    2382             : 
    2383       18633 :         return ref;
    2384             : }
    2385             : #endif /* ENABLE_VERIFIER */
    2386             : 
    2387             : /* resolve_create_unresolved_field *********************************************
    2388             :  
    2389             :    Create an unresolved_field struct for the given field access instruction
    2390             :   
    2391             :    IN:
    2392             :        referer..........the class containing the reference
    2393             :            refmethod........the method triggering the resolution (if any)
    2394             :            iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
    2395             : 
    2396             :    RETURN VALUE:
    2397             :        a pointer to a new unresolved_field struct, or
    2398             :            NULL if an exception has been thrown
    2399             : 
    2400             : *******************************************************************************/
    2401             : 
    2402       20923 : unresolved_field * resolve_create_unresolved_field(classinfo *referer,
    2403             :                                                                                                    methodinfo *refmethod,
    2404             :                                                                                                    instruction *iptr)
    2405             : {
    2406             :         unresolved_field *ref;
    2407       20923 :         constant_FMIref *fieldref = NULL;
    2408             : 
    2409             : #ifdef RESOLVE_VERBOSE
    2410             :         printf("create_unresolved_field\n");
    2411             :         printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
    2412             :         printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
    2413             :         printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
    2414             : #endif
    2415             : 
    2416       20923 :         ref = NEW(unresolved_field);
    2417       20923 :         ref->flags = 0;
    2418       20923 :         ref->referermethod = refmethod;
    2419       20923 :         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
    2420             : 
    2421       20923 :         switch (iptr->opc) {
    2422             :                 case ICMD_PUTFIELD:
    2423         614 :                         ref->flags |= RESOLVE_PUTFIELD;
    2424         614 :                         break;
    2425             : 
    2426             :                 case ICMD_PUTFIELDCONST:
    2427         100 :                         ref->flags |= RESOLVE_PUTFIELD;
    2428         100 :                         break;
    2429             : 
    2430             :                 case ICMD_PUTSTATIC:
    2431        1332 :                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
    2432        1332 :                         break;
    2433             : 
    2434             :                 case ICMD_PUTSTATICCONST:
    2435           9 :                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
    2436           9 :                         break;
    2437             : 
    2438             :                 case ICMD_GETFIELD:
    2439         677 :                         break;
    2440             : 
    2441             :                 case ICMD_GETSTATIC:
    2442       18191 :                         ref->flags |= RESOLVE_STATIC;
    2443       18191 :                         break;
    2444             : 
    2445             :                 default:
    2446           0 :                         assert(false);
    2447             :                         break;
    2448             :         }
    2449             : 
    2450       20923 :         fieldref = iptr->sx.s23.s3.fmiref;
    2451             : 
    2452       20923 :         assert(fieldref);
    2453             : 
    2454             : #ifdef RESOLVE_VERBOSE
    2455             : /*      printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
    2456             :         printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
    2457             :         printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
    2458             :         printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
    2459             :         fputc('\n',stdout);
    2460             : #endif
    2461             : 
    2462       20923 :         ref->fieldref = fieldref;
    2463             : 
    2464       20923 :         return ref;
    2465             : }
    2466             : 
    2467             : /* resolve_constrain_unresolved_field ******************************************
    2468             :  
    2469             :    Record subtype constraints for a field access.
    2470             :   
    2471             :    IN:
    2472             :        ref..............the unresolved_field structure of the access
    2473             :        referer..........the class containing the reference
    2474             :            refmethod........the method triggering the resolution (if any)
    2475             :            instanceti.......instance typeinfo, if available
    2476             :            valueti..........value typeinfo, if available
    2477             : 
    2478             :    RETURN VALUE:
    2479             :        true.............everything ok
    2480             :            false............an exception has been thrown
    2481             : 
    2482             : *******************************************************************************/
    2483             : 
    2484             : #if defined(ENABLE_VERIFIER)
    2485       21596 : bool resolve_constrain_unresolved_field(unresolved_field *ref,
    2486             :                                                                                 classinfo *referer, 
    2487             :                                                                                 methodinfo *refmethod,
    2488             :                                                                             typeinfo_t *instanceti,
    2489             :                                                                             typeinfo_t *valueti)
    2490             : {
    2491             :         constant_FMIref *fieldref;
    2492             :         int type;
    2493             :         typeinfo_t tinfo;
    2494             :         typedesc *fd;
    2495             : 
    2496       21596 :         assert(ref);
    2497             : 
    2498       21596 :         fieldref = ref->fieldref;
    2499       21596 :         assert(fieldref);
    2500             : 
    2501             : #ifdef RESOLVE_VERBOSE
    2502             :         printf("constrain_unresolved_field\n");
    2503             :         printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
    2504             :         printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
    2505             :         printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
    2506             : /*      printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
    2507             :         printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
    2508             :         printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
    2509             :         printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
    2510             :         fputc('\n',stdout);
    2511             : #endif
    2512             : 
    2513       21596 :         assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
    2514       21596 :         fd = fieldref->parseddesc.fd;
    2515       21596 :         assert(fd);
    2516             : 
    2517             :         /* record subtype constraints for the instance type, if any */
    2518       21596 :         if (instanceti) {
    2519             :                 typeinfo_t *insttip;
    2520             : 
    2521             :                 /* The instanceslot must contain a reference to a non-array type */
    2522        2061 :                 if (!instanceti->is_reference()) {
    2523           0 :                         exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
    2524           0 :                         return false;
    2525             :                 }
    2526        2061 :                 if (instanceti->is_array()) {
    2527           0 :                         exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
    2528           0 :                         return false;
    2529             :                 }
    2530             : 
    2531        2061 :                 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && instanceti->is_newobject())
    2532             :                 {
    2533             :                         /* The instruction writes a field in an uninitialized object. */
    2534             :                         /* This is only allowed when a field of an uninitialized 'this' object is */
    2535             :                         /* written inside an initialization method                                */
    2536             : 
    2537             :                         classinfo *initclass;
    2538           0 :                         instruction *ins = instanceti->newobject_instruction();
    2539             : 
    2540           0 :                         if (ins != NULL) {
    2541             :                                 exceptions_throw_verifyerror(refmethod,
    2542           0 :                                                 "accessing field of uninitialized object");
    2543           0 :                                 return false;
    2544             :                         }
    2545             :                         /* XXX check that class of field == refmethod->clazz */
    2546           0 :                         initclass = refmethod->clazz; /* XXX classrefs */
    2547           0 :                         assert(initclass->state & CLASS_LOADED);
    2548           0 :                         assert(initclass->state & CLASS_LINKED);
    2549             : 
    2550           0 :                         tinfo.init_class(initclass);
    2551           0 :                         insttip = &tinfo;
    2552             :                 }
    2553             :                 else {
    2554        2061 :                         insttip = instanceti;
    2555             :                 }
    2556        2061 :                 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
    2557             :                                         &(ref->instancetypes), insttip,
    2558             :                                         FIELDREF_CLASSNAME(fieldref)))
    2559           0 :                         return false;
    2560             :         }
    2561             :         else {
    2562       19535 :                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
    2563             :         }
    2564             : 
    2565             :         /* record subtype constraints for the value type, if any */
    2566       21596 :         type = fd->type;
    2567       23520 :         if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
    2568        1924 :                 assert(valueti);
    2569        1924 :                 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
    2570             :                                         &(ref->valueconstraints), valueti, 
    2571             :                                         fieldref->parseddesc.fd->classref->name))
    2572           0 :                         return false;
    2573             :         }
    2574             :         else {
    2575       19672 :                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
    2576             :         }
    2577             : 
    2578       21596 :         return true;
    2579             : }
    2580             : #endif /* ENABLE_VERIFIER */
    2581             : 
    2582             : /* resolve_create_unresolved_method ********************************************
    2583             :  
    2584             :    Create an unresolved_method struct for the given method invocation
    2585             :   
    2586             :    IN:
    2587             :        referer..........the class containing the reference
    2588             :            refmethod........the method triggering the resolution (if any)
    2589             :            iptr.............the INVOKE* instruction
    2590             : 
    2591             :    RETURN VALUE:
    2592             :        a pointer to a new unresolved_method struct
    2593             : 
    2594             : *******************************************************************************/
    2595             : 
    2596       64232 : unresolved_method * resolve_create_unresolved_method(classinfo *referer,
    2597             :                                                                                                          methodinfo *refmethod,
    2598             :                                                                                                          constant_FMIref *methodref,
    2599             :                                                                                                          bool invokestatic,
    2600             :                                                                                                          bool invokespecial)
    2601             : {
    2602             :         unresolved_method *ref;
    2603             : 
    2604       64232 :         assert(methodref);
    2605             : 
    2606             : #ifdef RESOLVE_VERBOSE
    2607             :         printf("create_unresolved_method\n");
    2608             :         printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
    2609             :         printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
    2610             :         printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
    2611             :         printf("    name   : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
    2612             :         printf("    desc   : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
    2613             : #endif
    2614             : 
    2615             :         /* allocate params if necessary */
    2616       64232 :         methodref->parseddesc.md->params_from_paramtypes(invokestatic ? ACC_STATIC : ACC_NONE);
    2617             : 
    2618             :         /* create the data structure */
    2619       64232 :         ref = NEW(unresolved_method);
    2620             :         ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
    2621       64232 :                            | ((invokespecial) ? RESOLVE_SPECIAL : 0);
    2622       64232 :         ref->referermethod = refmethod;
    2623       64232 :         ref->methodref = methodref;
    2624       64232 :         ref->paramconstraints = NULL;
    2625       64232 :         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
    2626             : 
    2627       64232 :         return ref;
    2628             : }
    2629             : 
    2630             : 
    2631             : /* resolve_constrain_unresolved_method_instance ********************************
    2632             : 
    2633             :    Record subtype constraints for the instance argument of a method call.
    2634             : 
    2635             :    IN:
    2636             :        ref..............the unresolved_method structure of the call
    2637             :        referer..........the class containing the reference
    2638             :            refmethod........the method triggering the resolution (if any)
    2639             :            iptr.............the INVOKE* instruction
    2640             : 
    2641             :    RETURN VALUE:
    2642             :        true.............everything ok
    2643             :            false............an exception has been thrown
    2644             : 
    2645             : *******************************************************************************/
    2646             : 
    2647             : #if defined(ENABLE_VERIFIER)
    2648       58818 : bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
    2649             :                                                                                                   methodinfo *refmethod,
    2650             :                                                                                                   typeinfo_t *instanceti,
    2651             :                                                                                                   bool invokespecial)
    2652             : {
    2653             :         constant_FMIref   *methodref;
    2654             :         constant_classref *instanceref;
    2655             :         typeinfo_t           tinfo;
    2656             :         typeinfo_t          *tip;
    2657             : 
    2658       58818 :         assert(ref);
    2659       58818 :         methodref = ref->methodref;
    2660       58818 :         assert(methodref);
    2661             : 
    2662             :         /* XXX clean this up */
    2663             :         instanceref = methodref->is_resolved()
    2664             :                 ? class_get_self_classref(methodref->p.method->clazz)
    2665       58818 :                 : methodref->p.classref;
    2666             : 
    2667             : #ifdef RESOLVE_VERBOSE
    2668             :         printf("resolve_constrain_unresolved_method_instance\n");
    2669             :         printf("    rmethod: "); method_println(refmethod);
    2670             :         printf("    mref   : "); method_methodref_println(methodref);
    2671             : #endif
    2672             : 
    2673             :         /* record subtype constraints for the instance type, if any */
    2674             : 
    2675       58818 :         if (invokespecial && instanceti->is_newobject())
    2676             :         {   /* XXX clean up */
    2677           0 :                 instruction *ins = instanceti->newobject_instruction();
    2678           0 :                 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c : to_classref_or_classinfo(refmethod->clazz);
    2679           0 :                 tip = &tinfo;
    2680           0 :                 if (!tip->init_class(initclass))
    2681           0 :                         return false;
    2682             :         }
    2683             :         else {
    2684       58818 :                 tip = instanceti;
    2685             :         }
    2686             : 
    2687       58818 :         if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
    2688             :                                 &(ref->instancetypes),tip,instanceref->name))
    2689           0 :                 return false;
    2690             : 
    2691       58818 :         return true;
    2692             : }
    2693             : #endif /* defined(ENABLE_VERIFIER) */
    2694             : 
    2695             : 
    2696             : /* resolve_constrain_unresolved_method_params  *********************************
    2697             :  
    2698             :    Record subtype constraints for the non-instance arguments of a method call.
    2699             :   
    2700             :    IN:
    2701             :        jd...............current jitdata (for looking up variables)
    2702             :        ref..............the unresolved_method structure of the call
    2703             :            refmethod........the method triggering the resolution (if any)
    2704             :            iptr.............the INVOKE* instruction
    2705             : 
    2706             :    RETURN VALUE:
    2707             :        true.............everything ok
    2708             :            false............an exception has been thrown
    2709             : 
    2710             : *******************************************************************************/
    2711             : 
    2712             : #if defined(ENABLE_VERIFIER)
    2713       66787 : bool resolve_constrain_unresolved_method_params(jitdata *jd,
    2714             :                                                                                                 unresolved_method *ref,
    2715             :                                                                                                 methodinfo *refmethod,
    2716             :                                                                                                 instruction *iptr)
    2717             : {
    2718             :         constant_FMIref *methodref;
    2719             :         varinfo *param;
    2720             :         methoddesc *md;
    2721             :         int i,j;
    2722             :         int type;
    2723             :         int instancecount;
    2724             : 
    2725       66787 :         assert(ref);
    2726       66787 :         methodref = ref->methodref;
    2727       66787 :         assert(methodref);
    2728       66787 :         md = methodref->parseddesc.md;
    2729       66787 :         assert(md);
    2730       66787 :         assert(md->params != NULL);
    2731             : 
    2732             : #ifdef RESOLVE_VERBOSE
    2733             :         printf("resolve_constrain_unresolved_method_params\n");
    2734             :         printf("    rmethod: "); method_println(refmethod);
    2735             :         printf("    mref   : "); method_methodref_println(methodref);
    2736             : #endif
    2737             : 
    2738       66787 :         instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
    2739             : 
    2740             :         /* record subtype constraints for the parameter types, if any */
    2741             : 
    2742      127799 :         for (i=md->paramcount-1-instancecount; i>=0; --i) {
    2743       61012 :                 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
    2744       61012 :                 type = md->paramtypes[i+instancecount].type;
    2745             : 
    2746       61012 :                 assert(param);
    2747       61012 :                 assert(type == param->type);
    2748             : 
    2749       61012 :                 if (type == TYPE_ADR) {
    2750       50265 :                         if (!ref->paramconstraints) {
    2751       38753 :                                 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
    2752       42887 :                                 for (j=md->paramcount-1-instancecount; j>i; --j)
    2753        4134 :                                         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
    2754             :                         }
    2755       50265 :                         assert(ref->paramconstraints);
    2756       50265 :                         if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
    2757             :                                                 ref->paramconstraints + i,&(param->typeinfo),
    2758             :                                                 md->paramtypes[i+instancecount].classref->name))
    2759           0 :                                 return false;
    2760             :                 }
    2761             :                 else {
    2762       10747 :                         if (ref->paramconstraints)
    2763        1055 :                                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
    2764             :                 }
    2765             :         }
    2766             : 
    2767       66787 :         return true;
    2768             : }
    2769             : #endif /* ENABLE_VERIFIER */
    2770             : 
    2771             : 
    2772             : /* resolve_constrain_unresolved_method_params_stackbased ***********************
    2773             :  
    2774             :    Record subtype constraints for the non-instance arguments of a method call.
    2775             :   
    2776             :    IN:
    2777             :        ref..............the unresolved_method structure of the call
    2778             :            refmethod........the method triggering the resolution (if any)
    2779             :            stack............TOS before the INVOKE instruction
    2780             : 
    2781             :    RETURN VALUE:
    2782             :        true.............everything ok
    2783             :            false............an exception has been thrown
    2784             : 
    2785             : *******************************************************************************/
    2786             : 
    2787             : #if defined(ENABLE_VERIFIER)
    2788           0 : bool resolve_constrain_unresolved_method_params_stackbased(
    2789             :                 unresolved_method *ref,
    2790             :                 methodinfo *refmethod,
    2791             :                 typedescriptor_t *stack)
    2792             : {
    2793             :         constant_FMIref *methodref;
    2794             :         typedescriptor_t *param;
    2795             :         methoddesc *md;
    2796             :         int i,j;
    2797             :         int type;
    2798             :         int instancecount;
    2799             : 
    2800           0 :         assert(ref);
    2801           0 :         methodref = ref->methodref;
    2802           0 :         assert(methodref);
    2803           0 :         md = methodref->parseddesc.md;
    2804           0 :         assert(md);
    2805           0 :         assert(md->params != NULL);
    2806             : 
    2807             : #ifdef RESOLVE_VERBOSE
    2808             :         printf("resolve_constrain_unresolved_method_params_stackbased\n");
    2809             :         printf("    rmethod: "); method_println(refmethod);
    2810             :         printf("    mref   : "); method_methodref_println(methodref);
    2811             : #endif
    2812             : 
    2813           0 :         instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
    2814             : 
    2815             :         /* record subtype constraints for the parameter types, if any */
    2816             : 
    2817           0 :         param = stack - (md->paramslots - 1 - instancecount);
    2818             : 
    2819           0 :         for (i = instancecount; i < md->paramcount; ++i) {
    2820           0 :                 type = md->paramtypes[i].type;
    2821             : 
    2822           0 :                 assert(type == param->type);
    2823             : 
    2824           0 :                 if (type == TYPE_ADR) {
    2825           0 :                         if (!ref->paramconstraints) {
    2826           0 :                                 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
    2827           0 :                                 for (j = 0; j < i - instancecount; ++j)
    2828           0 :                                         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
    2829             :                         }
    2830           0 :                         assert(ref->paramconstraints);
    2831           0 :                         if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
    2832             :                                                 ref->paramconstraints + i - instancecount,&(param->typeinfo),
    2833             :                                                 md->paramtypes[i].classref->name))
    2834           0 :                                 return false;
    2835             :                 }
    2836             :                 else {
    2837           0 :                         if (ref->paramconstraints)
    2838           0 :                                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
    2839             :                 }
    2840             : 
    2841           0 :                 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
    2842             :         }
    2843             : 
    2844           0 :         return true;
    2845             : }
    2846             : #endif /* ENABLE_VERIFIER */
    2847             : 
    2848             : 
    2849             : /******************************************************************************/
    2850             : /* FREEING MEMORY                                                             */
    2851             : /******************************************************************************/
    2852             : 
    2853             : #ifdef ENABLE_VERIFIER
    2854           0 : inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
    2855             : {
    2856           0 :         if (list) {
    2857           0 :                 classref_or_classinfo *p = list;
    2858             : 
    2859             :                 /* this is silly. we *only* need to count the elements for MFREE */
    2860           0 :                 while ((p++)->any)
    2861             :                         ;
    2862           0 :                 MFREE(list,classref_or_classinfo,(p - list));
    2863             :         }
    2864           0 : }
    2865             : #endif /* ENABLE_VERIFIER */
    2866             : 
    2867             : /* unresolved_class_free *******************************************************
    2868             :  
    2869             :    Free the memory used by an unresolved_class
    2870             :   
    2871             :    IN:
    2872             :        ref..............the unresolved_class
    2873             : 
    2874             : *******************************************************************************/
    2875             : 
    2876           0 : void unresolved_class_free(unresolved_class *ref)
    2877             : {
    2878           0 :         assert(ref);
    2879             : 
    2880             : #ifdef ENABLE_VERIFIER
    2881           0 :         unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
    2882             : #endif
    2883           0 :         FREE(ref,unresolved_class);
    2884           0 : }
    2885             : 
    2886             : /* unresolved_field_free *******************************************************
    2887             :  
    2888             :    Free the memory used by an unresolved_field
    2889             :   
    2890             :    IN:
    2891             :        ref..............the unresolved_field
    2892             : 
    2893             : *******************************************************************************/
    2894             : 
    2895           0 : void unresolved_field_free(unresolved_field *ref)
    2896             : {
    2897           0 :         assert(ref);
    2898             : 
    2899             : #ifdef ENABLE_VERIFIER
    2900           0 :         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
    2901           0 :         unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
    2902             : #endif
    2903           0 :         FREE(ref,unresolved_field);
    2904           0 : }
    2905             : 
    2906             : /* unresolved_method_free ******************************************************
    2907             :  
    2908             :    Free the memory used by an unresolved_method
    2909             :   
    2910             :    IN:
    2911             :        ref..............the unresolved_method
    2912             : 
    2913             : *******************************************************************************/
    2914             : 
    2915           0 : void unresolved_method_free(unresolved_method *ref)
    2916             : {
    2917           0 :         assert(ref);
    2918             : 
    2919             : #ifdef ENABLE_VERIFIER
    2920           0 :         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
    2921           0 :         if (ref->paramconstraints) {
    2922             :                 int i;
    2923           0 :                 int count = ref->methodref->parseddesc.md->paramcount;
    2924             : 
    2925           0 :                 for (i=0; i<count; ++i)
    2926           0 :                         unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
    2927           0 :                 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
    2928             :         }
    2929             : #endif
    2930           0 :         FREE(ref,unresolved_method);
    2931           0 : }
    2932             : 
    2933             : /******************************************************************************/
    2934             : /* DEBUG DUMPS                                                                */
    2935             : /******************************************************************************/
    2936             : 
    2937             : #if !defined(NDEBUG)
    2938             : 
    2939             : /* unresolved_subtype_set_debug_dump *******************************************
    2940             : 
    2941             :    Print debug info for unresolved_subtype_set to stream
    2942             : 
    2943             :    IN:
    2944             :        stset............the unresolved_subtype_set
    2945             :            file.............the stream
    2946             : 
    2947             : *******************************************************************************/
    2948             : 
    2949           0 : void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
    2950             : {
    2951             :         classref_or_classinfo *p;
    2952             : 
    2953           0 :         if (SUBTYPESET_IS_EMPTY(*stset)) {
    2954           0 :                 fprintf(file,"        (empty)\n");
    2955             :         }
    2956             :         else {
    2957           0 :                 p = stset->subtyperefs;
    2958           0 :                 for (;p->any; ++p) {
    2959           0 :                         if (p->is_classref()) {
    2960           0 :                                 fprintf(file,"        ref: ");
    2961           0 :                                 utf_fprint_printable_ascii(file,p->ref->name);
    2962             :                         }
    2963             :                         else {
    2964           0 :                                 fprintf(file,"        cls: ");
    2965           0 :                                 utf_fprint_printable_ascii(file,p->cls->name);
    2966             :                         }
    2967           0 :                         fputc('\n',file);
    2968             :                 }
    2969             :         }
    2970           0 : }
    2971             : 
    2972             : /* unresolved_class_debug_dump *************************************************
    2973             : 
    2974             :    Print debug info for unresolved_class to stream
    2975             : 
    2976             :    IN:
    2977             :        ref..............the unresolved_class
    2978             :            file.............the stream
    2979             : 
    2980             : *******************************************************************************/
    2981             : 
    2982           0 : void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
    2983             : {
    2984           0 :         fprintf(file,"unresolved_class(%p):\n",(void *)ref);
    2985           0 :         if (ref) {
    2986           0 :                 fprintf(file,"    referer   : ");
    2987           0 :                 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
    2988           0 :                 fprintf(file,"    refmethod : ");
    2989           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
    2990           0 :                 fprintf(file,"    refmethodd: ");
    2991           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
    2992           0 :                 fprintf(file,"    classname : ");
    2993           0 :                 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
    2994           0 :                 fprintf(file,"    subtypeconstraints:\n");
    2995           0 :                 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
    2996             :         }
    2997           0 : }
    2998             : 
    2999             : /* unresolved_field_debug_dump *************************************************
    3000             :  
    3001             :    Print debug info for unresolved_field to stream
    3002             :   
    3003             :    IN:
    3004             :        ref..............the unresolved_field
    3005             :            file.............the stream
    3006             : 
    3007             : *******************************************************************************/
    3008             : 
    3009           0 : void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
    3010             : {
    3011           0 :         fprintf(file,"unresolved_field(%p):\n",(void *)ref);
    3012           0 :         if (ref) {
    3013           0 :                 fprintf(file,"    referer   : ");
    3014           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
    3015           0 :                 fprintf(file,"    refmethod : ");
    3016           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
    3017           0 :                 fprintf(file,"    refmethodd: ");
    3018           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
    3019           0 :                 fprintf(file,"    classname : ");
    3020           0 :                 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
    3021           0 :                 fprintf(file,"    name      : ");
    3022           0 :                 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
    3023           0 :                 fprintf(file,"    descriptor: ");
    3024           0 :                 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
    3025           0 :                 fprintf(file,"    parseddesc: ");
    3026           0 :                 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
    3027           0 :                 fprintf(file,"    flags     : %04x\n",ref->flags);
    3028           0 :                 fprintf(file,"    instancetypes:\n");
    3029           0 :                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
    3030           0 :                 fprintf(file,"    valueconstraints:\n");
    3031           0 :                 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
    3032             :         }
    3033           0 : }
    3034             : 
    3035             : /* unresolved_method_debug_dump ************************************************
    3036             :  
    3037             :    Print debug info for unresolved_method to stream
    3038             :   
    3039             :    IN:
    3040             :        ref..............the unresolved_method
    3041             :            file.............the stream
    3042             : 
    3043             : *******************************************************************************/
    3044             : 
    3045           0 : void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
    3046             : {
    3047             :         int i;
    3048             : 
    3049           0 :         fprintf(file,"unresolved_method(%p):\n",(void *)ref);
    3050           0 :         if (ref) {
    3051           0 :                 fprintf(file,"    referer   : ");
    3052           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
    3053           0 :                 fprintf(file,"    refmethod : ");
    3054           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
    3055           0 :                 fprintf(file,"    refmethodd: ");
    3056           0 :                 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
    3057           0 :                 fprintf(file,"    classname : ");
    3058           0 :                 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
    3059           0 :                 fprintf(file,"    name      : ");
    3060           0 :                 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
    3061           0 :                 fprintf(file,"    descriptor: ");
    3062           0 :                 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
    3063           0 :                 fprintf(file,"    parseddesc: ");
    3064           0 :                 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
    3065           0 :                 fprintf(file,"    flags     : %04x\n",ref->flags);
    3066           0 :                 fprintf(file,"    instancetypes:\n");
    3067           0 :                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
    3068           0 :                 fprintf(file,"    paramconstraints:\n");
    3069           0 :                 if (ref->paramconstraints) {
    3070           0 :                         for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
    3071           0 :                                 fprintf(file,"      param %d:\n",i);
    3072           0 :                                 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
    3073             :                         }
    3074             :                 }
    3075             :                 else {
    3076           0 :                         fprintf(file,"      (empty)\n");
    3077             :                 }
    3078             :         }
    3079           0 : }
    3080             : #endif /* !defined(NDEBUG) */
    3081             : 
    3082             : 
    3083             : /*
    3084             :  * These are local overrides for various environment variables in Emacs.
    3085             :  * Please do not remove this and leave it at the end of the file, where
    3086             :  * Emacs will automagically detect them.
    3087             :  * ---------------------------------------------------------------------
    3088             :  * Local variables:
    3089             :  * mode: c++
    3090             :  * indent-tabs-mode: t
    3091             :  * c-basic-offset: 4
    3092             :  * tab-width: 4
    3093             :  * End:
    3094             :  * vim:noexpandtab:sw=4:ts=4:
    3095             :  */

Generated by: LCOV version 1.11