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