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