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