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