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