* src/vm/class.c: Don't initialize classes to NULL.
[cacao.git] / src / vm / resolve.c
1 /* src/vm/resolve.c - resolving classes/interfaces/fields/methods
2
3    Copyright (C) 1996-2005, 2006 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    Contact: cacao@cacaojvm.org
26
27    Authors: Edwin Steiner
28
29    Changes: Christan Thalinger
30
31    $Id: resolve.c 4690 2006-03-27 11:37:46Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39
40 #include "mm/memory.h"
41 #include "vm/resolve.h"
42 #include "vm/access.h"
43 #include "vm/classcache.h"
44 #include "vm/descriptor.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/linker.h"
48 #include "vm/loader.h"
49 #include "vm/stringlocal.h"
50 #include "vm/jit/jit.h"
51 #include "vm/jit/verify/typeinfo.h"
52
53
54 /******************************************************************************/
55 /* DEBUG HELPERS                                                              */
56 /******************************************************************************/
57
58 /*#define RESOLVE_VERBOSE*/
59
60 /******************************************************************************/
61 /* CLASS RESOLUTION                                                           */
62 /******************************************************************************/
63
64 /* resolve_class_from_name *****************************************************
65  
66    Resolve a symbolic class reference
67   
68    IN:
69        referer..........the class containing the reference
70        refmethod........the method from which resolution was triggered
71                         (may be NULL if not applicable)
72        classname........class name to resolve
73        mode.............mode of resolution:
74                             resolveLazy...only resolve if it does not
75                                           require loading classes
76                             resolveEager..load classes if necessary
77            checkaccess......if true, access rights to the class are checked
78            link.............if true, guarantee that the returned class, if any,
79                             has been linked
80   
81    OUT:
82        *result..........set to result of resolution, or to NULL if
83                         the reference has not been resolved
84                         In the case of an exception, *result is
85                         guaranteed to be set to NULL.
86   
87    RETURN VALUE:
88        true.............everything ok 
89                         (*result may still be NULL for resolveLazy)
90        false............an exception has been thrown
91
92    NOTE:
93        The returned class is *not* guaranteed to be linked!
94            (It is guaranteed to be loaded, though.)
95    
96 *******************************************************************************/
97
98 bool resolve_class_from_name(classinfo *referer,
99                                                          methodinfo *refmethod,
100                                                          utf *classname,
101                                                          resolve_mode_t mode,
102                                                          bool checkaccess,
103                                                          bool link,
104                                                          classinfo **result)
105 {
106         classinfo *cls = NULL;
107         char *utf_ptr;
108         int len;
109         
110         assert(result);
111         assert(referer);
112         assert(classname);
113         assert(mode == resolveLazy || mode == resolveEager);
114         
115         *result = NULL;
116
117 #ifdef RESOLVE_VERBOSE
118         fprintf(stderr,"resolve_class_from_name(");
119         utf_fprint(stderr,referer->name);
120         fprintf(stderr,",%p,",referer->classloader);
121         utf_fprint(stderr,classname);
122         fprintf(stderr,",%d,%d)\n",(int)checkaccess,(int)link);
123 #endif
124
125         /* lookup if this class has already been loaded */
126
127         cls = classcache_lookup(referer->classloader, classname);
128
129 #ifdef RESOLVE_VERBOSE
130         fprintf(stderr,"    lookup result: %p\n",(void*)cls);
131 #endif
132
133         if (!cls) {
134                 /* resolve array types */
135
136                 if (classname->text[0] == '[') {
137                         utf_ptr = classname->text + 1;
138                         len = classname->blength - 1;
139
140                         /* classname is an array type name */
141
142                         switch (*utf_ptr) {
143                                 case 'L':
144                                         utf_ptr++;
145                                         len -= 2;
146                                         /* FALLTHROUGH */
147                                 case '[':
148                                         /* the component type is a reference type */
149                                         /* resolve the component type */
150                                         if (!resolve_class_from_name(referer,refmethod,
151                                                                            utf_new(utf_ptr,len),
152                                                                            mode,checkaccess,link,&cls))
153                                                 return false; /* exception */
154                                         if (!cls) {
155                                                 assert(mode == resolveLazy);
156                                                 return true; /* be lazy */
157                                         }
158                                         /* create the array class */
159                                         cls = class_array_of(cls,false);
160                                         if (!cls)
161                                                 return false; /* exception */
162                         }
163                 }
164                 else {
165                         /* the class has not been loaded, yet */
166                         if (mode == resolveLazy)
167                                 return true; /* be lazy */
168                 }
169
170 #ifdef RESOLVE_VERBOSE
171                 fprintf(stderr,"    loading...\n");
172 #endif
173
174                 /* load the class */
175                 if (!cls) {
176                         if (!(cls = load_class_from_classloader(classname,
177                                                                                                         referer->classloader)))
178                                 return false; /* exception */
179                 }
180         }
181
182         /* the class is now loaded */
183         assert(cls);
184         assert(cls->state & CLASS_LOADED);
185
186 #ifdef RESOLVE_VERBOSE
187         fprintf(stderr,"    checking access rights...\n");
188 #endif
189         
190         /* check access rights of referer to refered class */
191         if (checkaccess && !access_is_accessible_class(referer,cls)) {
192                 int msglen;
193                 char *message;
194
195                 msglen = utf_strlen(cls->name) + utf_strlen(referer->name) + 100;
196                 message = MNEW(char,msglen);
197                 strcpy(message,"class is not accessible (");
198                 utf_sprint_classname(message+strlen(message),cls->name);
199                 strcat(message," from ");
200                 utf_sprint_classname(message+strlen(message),referer->name);
201                 strcat(message,")");
202                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
203                 MFREE(message,char,msglen);
204                 return false; /* exception */
205         }
206
207         /* link the class if necessary */
208         if (link) {
209                 if (!(cls->state & CLASS_LINKED))
210                         if (!link_class(cls))
211                                 return false; /* exception */
212
213                 assert(cls->state & CLASS_LINKED);
214         }
215
216         /* resolution succeeds */
217 #ifdef RESOLVE_VERBOSE
218         fprintf(stderr,"    success.\n");
219 #endif
220         *result = cls;
221         return true;
222 }
223
224 /* resolve_classref ************************************************************
225  
226    Resolve a symbolic class reference
227   
228    IN:
229        refmethod........the method from which resolution was triggered
230                         (may be NULL if not applicable)
231        ref..............class reference
232        mode.............mode of resolution:
233                             resolveLazy...only resolve if it does not
234                                           require loading classes
235                             resolveEager..load classes if necessary
236            checkaccess......if true, access rights to the class are checked
237            link.............if true, guarantee that the returned class, if any,
238                             has been linked
239   
240    OUT:
241        *result..........set to result of resolution, or to NULL if
242                         the reference has not been resolved
243                         In the case of an exception, *result is
244                         guaranteed to be set to NULL.
245   
246    RETURN VALUE:
247        true.............everything ok 
248                         (*result may still be NULL for resolveLazy)
249        false............an exception has been thrown
250    
251 *******************************************************************************/
252
253 bool resolve_classref(methodinfo *refmethod,
254                                           constant_classref *ref,
255                                           resolve_mode_t mode,
256                                           bool checkaccess,
257                                           bool link,
258                                           classinfo **result)
259 {
260         return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
261 }
262
263 /* resolve_classref_or_classinfo ***********************************************
264  
265    Resolve a symbolic class reference if necessary
266   
267    IN:
268        refmethod........the method from which resolution was triggered
269                         (may be NULL if not applicable)
270        cls..............class reference or classinfo
271        mode.............mode of resolution:
272                             resolveLazy...only resolve if it does not
273                                           require loading classes
274                             resolveEager..load classes if necessary
275            checkaccess......if true, access rights to the class are checked
276            link.............if true, guarantee that the returned class, if any,
277                             has been linked
278   
279    OUT:
280        *result..........set to result of resolution, or to NULL if
281                         the reference has not been resolved
282                         In the case of an exception, *result is
283                         guaranteed to be set to NULL.
284   
285    RETURN VALUE:
286        true.............everything ok 
287                         (*result may still be NULL for resolveLazy)
288        false............an exception has been thrown
289    
290 *******************************************************************************/
291
292 bool resolve_classref_or_classinfo(methodinfo *refmethod,
293                                                                    classref_or_classinfo cls,
294                                                                    resolve_mode_t mode,
295                                                                    bool checkaccess,
296                                                                    bool link,
297                                                                    classinfo **result)
298 {
299         classinfo         *c;
300         
301         assert(cls.any);
302         assert(mode == resolveEager || mode == resolveLazy);
303         assert(result);
304
305 #ifdef RESOLVE_VERBOSE
306         fprintf(stderr,"resolve_classref_or_classinfo(");
307         utf_fprint(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
308         fprintf(stderr,",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
309 #endif
310
311         *result = NULL;
312
313         if (IS_CLASSREF(cls)) {
314                 /* we must resolve this reference */
315
316                 if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
317                                                                          mode, checkaccess, link, &c))
318                         goto return_exception;
319
320         } else {
321                 /* cls has already been resolved */
322                 c = cls.cls;
323                 assert(c->state & CLASS_LOADED);
324         }
325         assert(c || (mode == resolveLazy));
326
327         if (!c)
328                 return true; /* be lazy */
329         
330         assert(c);
331         assert(c->state & CLASS_LOADED);
332
333         if (link) {
334                 if (!(c->state & CLASS_LINKED))
335                         if (!link_class(c))
336                                 goto return_exception;
337
338                 assert(c->state & CLASS_LINKED);
339         }
340
341         /* succeeded */
342         *result = c;
343         return true;
344
345  return_exception:
346         *result = NULL;
347         return false;
348 }
349
350
351 /* resolve_class_from_typedesc *************************************************
352  
353    Return a classinfo * for the given type descriptor
354   
355    IN:
356        d................type descriptor
357            checkaccess......if true, access rights to the class are checked
358            link.............if true, guarantee that the returned class, if any,
359                             has been linked
360    OUT:
361        *result..........set to result of resolution, or to NULL if
362                         the reference has not been resolved
363                         In the case of an exception, *result is
364                         guaranteed to be set to NULL.
365   
366    RETURN VALUE:
367        true.............everything ok 
368        false............an exception has been thrown
369
370    NOTE:
371        This function always resolved eagerly.
372    
373 *******************************************************************************/
374
375 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
376 {
377         classinfo *cls;
378         
379         assert(d);
380         assert(result);
381
382         *result = NULL;
383
384 #ifdef RESOLVE_VERBOSE
385         fprintf(stderr,"resolve_class_from_typedesc(");
386         descriptor_debug_print_typedesc(stderr,d);
387         fprintf(stderr,",%i,%i)\n",(int)checkaccess,(int)link);
388 #endif
389
390         if (d->type == TYPE_ADR) {
391                 /* a reference type */
392                 assert(d->classref);
393                 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
394                                                                                    resolveEager,checkaccess,link,&cls))
395                         return false; /* exception */
396         }
397         else {
398                 /* a primitive type */
399                 cls = primitivetype_table[d->decltype].class_primitive;
400                 assert(cls->state & CLASS_LOADED);
401                 if (!(cls->state & CLASS_LINKED))
402                         if (!link_class(cls))
403                                 return false; /* exception */
404         }
405         assert(cls);
406         assert(cls->state & CLASS_LOADED);
407         assert(!link || (cls->state & CLASS_LINKED));
408
409 #ifdef RESOLVE_VERBOSE
410         fprintf(stderr,"    result = ");utf_fprint(stderr,cls->name);fprintf(stderr,"\n");
411 #endif
412
413         *result = cls;
414         return true;
415 }
416
417 /******************************************************************************/
418 /* SUBTYPE SET CHECKS                                                         */
419 /******************************************************************************/
420
421 #ifdef ENABLE_VERIFIER
422
423 /* resolve_and_check_subtype_set ***********************************************
424  
425    Resolve the references in the given set and test subtype relationships
426   
427    IN:
428        referer..........the class containing the references
429        refmethod........the method triggering the resolution
430        ref..............a set of class/interface references
431                         (may be empty)
432        type.............the type to test against the set
433        reversed.........if true, test if type is a subtype of
434                         the set members, instead of the other
435                         way round
436        mode.............mode of resolution:
437                             resolveLazy...only resolve if it does not
438                                           require loading classes
439                             resolveEager..load classes if necessary
440        error............which type of exception to throw if
441                         the test fails. May be:
442                             resolveLinkageError, or
443                             resolveIllegalAccessError
444                                                 IMPORTANT: If error==resolveIllegalAccessError,
445                                                 then array types in the set are skipped.
446
447    OUT:
448        *checked.........set to true if all checks were performed,
449                             otherwise set to false
450                             (This is guaranteed to be true if mode was
451                                                 resolveEager and no exception occured.)
452                                                 If checked == NULL, this parameter is not used.
453   
454    RETURN VALUE:
455        true.............the check succeeded
456        false............the check failed. An exception has been
457                         thrown.
458    
459    NOTE:
460        The references in the set are resolved first, so any
461        exception which may occurr during resolution may
462        be thrown by this function.
463    
464 *******************************************************************************/
465
466 bool resolve_and_check_subtype_set(classinfo *referer,methodinfo *refmethod,
467                                                                    unresolved_subtype_set *ref,
468                                                                    classref_or_classinfo typeref,
469                                                                    bool reversed,
470                                                                    resolve_mode_t mode,
471                                                                    resolve_err_t error,
472                                                                    bool *checked)
473 {
474         classref_or_classinfo *setp;
475         classinfo *result;
476         classinfo *type;
477         typeinfo resultti;
478         typeinfo typeti;
479         char *message;
480         int msglen;
481         typecheck_result r;
482
483         assert(referer);
484         assert(ref);
485         assert(typeref.any);
486         assert(mode == resolveLazy || mode == resolveEager);
487         assert(error == resolveLinkageError || error == resolveIllegalAccessError);
488
489 #ifdef RESOLVE_VERBOSE
490         fprintf(stderr,"resolve_and_check_subtype_set\n");
491         unresolved_subtype_set_debug_dump(ref,stderr);
492         if (IS_CLASSREF(typeref)) {
493                 fprintf(stderr,"    ref: ");utf_fprint(stderr,typeref.ref->name);
494         }
495         else {
496                 fprintf(stderr,"    cls: ");utf_fprint(stderr,typeref.cls->name);
497         }
498         fprintf(stderr,"\n");
499 #endif
500
501         setp = ref->subtyperefs;
502
503         /* an empty set of tests always succeeds */
504         if (!setp || !setp->any) {
505                 if (checked)
506                         *checked = true;
507                 return true;
508         }
509
510         if (checked)
511                 *checked = false;
512
513         /* first resolve the type if necessary */
514         if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&type))
515                 return false; /* exception */
516         if (!type)
517                 return true; /* be lazy */
518
519         assert(type);
520         assert(type->state & CLASS_LOADED);
521         assert(type->state & CLASS_LINKED);
522         typeinfo_init_classinfo(&typeti,type);
523
524         for (; setp->any; ++setp) {
525                 /* first resolve the set member if necessary */
526                 if (!resolve_classref_or_classinfo(refmethod,*setp,mode,false,true,&result)) {
527                         /* the type could not be resolved. therefore we are sure that  */
528                         /* no instances of this type will ever exist -> skip this test */
529                         /* XXX this assumes that class loading has invariant results (as in JVM spec) */
530                         *exceptionptr = NULL;
531                         continue;
532                 }
533                 if (!result)
534                         return true; /* be lazy */
535
536                 assert(result);
537                 assert(result->state & CLASS_LOADED);
538                 assert(result->state & CLASS_LINKED);
539
540
541                 /* do not check access to protected members of arrays */
542                 if (error == resolveIllegalAccessError && result->name->text[0] == '[') {
543                         continue;
544                 }
545
546 #ifdef RESOLVE_VERBOSE
547                 fprintf(stderr,"performing subclass test:\n");
548                 fprintf(stderr,"    ");utf_fprint(stderr,result->name);fputc('\n',stderr);
549                 fprintf(stderr,"  must be a %s of\n",(reversed) ? "superclass" : "subclass");
550                 fprintf(stderr,"    ");utf_fprint(stderr,type->name);fputc('\n',stderr);
551 #endif
552
553                 /* now check the subtype relationship */
554                 typeinfo_init_classinfo(&resultti,result);
555                 if (reversed) {
556                         /* we must test against `true` because `MAYBE` is also != 0 */
557                         r = typeinfo_is_assignable_to_class(&typeti,CLASSREF_OR_CLASSINFO(result));
558                         if (r == typecheck_FAIL)
559                                 return false;
560                         if (r != typecheck_TRUE) {
561 #ifdef RESOLVE_VERBOSE
562                                 fprintf(stderr,"reversed subclass test failed\n");
563 #endif
564                                 goto throw_error;
565                         }
566                 }
567                 else {
568                         /* we must test against `true` because `MAYBE` is also != 0 */
569                         r = typeinfo_is_assignable_to_class(&resultti,CLASSREF_OR_CLASSINFO(type));
570                         if (r == typecheck_FAIL)
571                                 return false;
572                         if (r != typecheck_TRUE) {
573 #ifdef RESOLVE_VERBOSE
574                                 fprintf(stderr,"subclass test failed\n");
575 #endif
576                                 goto throw_error;
577                         }
578                 }
579         }
580         
581         /* check succeeds */
582         if (checked)
583                 *checked = true;
584         return true;
585
586 throw_error:
587         msglen = utf_strlen(result->name) + utf_strlen(type->name) + 200;
588         message = MNEW(char,msglen);
589         strcpy(message,(error == resolveIllegalAccessError) ?
590                         "illegal access to protected member ("
591                         : "subtype constraint violated (");
592         utf_sprint_classname(message+strlen(message),result->name);
593         strcat(message," is not a subclass of ");
594         utf_sprint_classname(message+strlen(message),type->name);
595         strcat(message,")");
596         if (error == resolveIllegalAccessError)
597                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
598         else
599                 *exceptionptr = exceptions_new_linkageerror(message,NULL);
600         MFREE(message,char,msglen);
601         return false; /* exception */
602 }
603
604 #endif /* ENABLE_VERIFIER */
605
606 /******************************************************************************/
607 /* CLASS RESOLUTION                                                           */
608 /******************************************************************************/
609
610 /* resolve_class ***************************************************************
611  
612    Resolve an unresolved class reference. The class is also linked.
613   
614    IN:
615        ref..............struct containing the reference
616        mode.............mode of resolution:
617                             resolveLazy...only resolve if it does not
618                                           require loading classes
619                             resolveEager..load classes if necessary
620            checkaccess......if true, access rights to the class are checked
621    
622    OUT:
623        *result..........set to the result of resolution, or to NULL if
624                         the reference has not been resolved
625                         In the case of an exception, *result is
626                         guaranteed to be set to NULL.
627   
628    RETURN VALUE:
629        true.............everything ok 
630                         (*result may still be NULL for resolveLazy)
631        false............an exception has been thrown
632    
633 *******************************************************************************/
634
635 #ifdef ENABLE_VERIFIER
636 bool resolve_class(unresolved_class *ref,
637                                    resolve_mode_t mode,
638                                    bool checkaccess,
639                                    classinfo **result)
640 {
641         classinfo *cls;
642         bool checked;
643         
644         assert(ref);
645         assert(result);
646         assert(mode == resolveLazy || mode == resolveEager);
647
648         *result = NULL;
649
650 #ifdef RESOLVE_VERBOSE
651         unresolved_class_debug_dump(ref,stderr);
652 #endif
653
654         /* first we must resolve the class */
655         if (!resolve_classref(ref->referermethod,
656                                               ref->classref,mode,checkaccess,true,&cls))
657         {
658                 /* the class reference could not be resolved */
659                 return false; /* exception */
660         }
661         if (!cls)
662                 return true; /* be lazy */
663
664         assert(cls);
665         assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
666
667         /* now we check the subtype constraints */
668         if (!resolve_and_check_subtype_set(ref->classref->referer,ref->referermethod,
669                                                                            &(ref->subtypeconstraints),
670                                                                            CLASSREF_OR_CLASSINFO(cls),
671                                                                            false,
672                                                                            mode,
673                                                                            resolveLinkageError,&checked))
674         {
675                 return false; /* exception */
676         }
677         if (!checked)
678                 return true; /* be lazy */
679
680         /* succeed */
681         *result = cls;
682         return true;
683 }
684 #endif /* ENABLE_VERIFIER */
685
686 /* resolve_classref_eager ******************************************************
687  
688    Resolve an unresolved class reference eagerly. The class is also linked and
689    access rights to the class are checked.
690   
691    IN:
692        ref..............constant_classref to the class
693    
694    RETURN VALUE:
695        classinfo * to the class, or
696            NULL if an exception has been thrown
697    
698 *******************************************************************************/
699
700 classinfo * resolve_classref_eager(constant_classref *ref)
701 {
702         classinfo *c;
703
704         if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
705                 return NULL;
706
707         return c;
708 }
709
710 /* resolve_classref_eager_nonabstract ******************************************
711  
712    Resolve an unresolved class reference eagerly. The class is also linked and
713    access rights to the class are checked. A check is performed that the class
714    is not abstract.
715   
716    IN:
717        ref..............constant_classref to the class
718    
719    RETURN VALUE:
720        classinfo * to the class, or
721            NULL if an exception has been thrown
722    
723 *******************************************************************************/
724
725 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
726 {
727         classinfo *c;
728
729         if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
730                 return NULL;
731
732         /* ensure that the class is not abstract */
733
734         if (c->flags & ACC_ABSTRACT) {
735                 *exceptionptr = new_verifyerror(NULL,"creating instance of abstract class");
736                 return NULL;
737         }
738
739         return c;
740 }
741
742 /* resolve_class_eager *********************************************************
743  
744    Resolve an unresolved class reference eagerly. The class is also linked and
745    access rights to the class are checked.
746   
747    IN:
748        ref..............struct containing the reference
749    
750    RETURN VALUE:
751        classinfo * to the class, or
752            NULL if an exception has been thrown
753    
754 *******************************************************************************/
755
756 #ifdef ENABLE_VERIFIER
757 classinfo * resolve_class_eager(unresolved_class *ref)
758 {
759         classinfo *c;
760
761         if (!resolve_class(ref,resolveEager,true,&c))
762                 return NULL;
763
764         return c;
765 }
766 #endif /* ENABLE_VERIFIER */
767
768 /******************************************************************************/
769 /* FIELD RESOLUTION                                                           */
770 /******************************************************************************/
771
772 /* resolve_field ***************************************************************
773  
774    Resolve an unresolved field reference
775   
776    IN:
777        ref..............struct containing the reference
778        mode.............mode of resolution:
779                             resolveLazy...only resolve if it does not
780                                           require loading classes
781                             resolveEager..load classes if necessary
782   
783    OUT:
784        *result..........set to the result of resolution, or to NULL if
785                         the reference has not been resolved
786                         In the case of an exception, *result is
787                         guaranteed to be set to NULL.
788   
789    RETURN VALUE:
790        true.............everything ok 
791                         (*result may still be NULL for resolveLazy)
792        false............an exception has been thrown
793    
794 *******************************************************************************/
795
796 bool resolve_field(unresolved_field *ref,
797                                    resolve_mode_t mode,
798                                    fieldinfo **result)
799 {
800         classinfo *referer;
801         classinfo *container;
802         classinfo *declarer;
803         constant_classref *fieldtyperef;
804         fieldinfo *fi;
805         bool checked;
806         
807         assert(ref);
808         assert(result);
809         assert(mode == resolveLazy || mode == resolveEager);
810
811         *result = NULL;
812
813 #ifdef RESOLVE_VERBOSE
814         unresolved_field_debug_dump(ref,stderr);
815 #endif
816
817         /* the class containing the reference */
818
819         referer = ref->fieldref->classref->referer;
820         assert(referer);
821
822         /* first we must resolve the class containg the field */
823         if (!resolve_class_from_name(referer,ref->referermethod,
824                                            ref->fieldref->classref->name,mode,true,true,&container))
825         {
826                 /* the class reference could not be resolved */
827                 return false; /* exception */
828         }
829         if (!container)
830                 return true; /* be lazy */
831
832         assert(container);
833         assert(container->state & CLASS_LOADED);
834         assert(container->state & CLASS_LINKED);
835
836         /* now we must find the declaration of the field in `container`
837          * or one of its superclasses */
838
839 #ifdef RESOLVE_VERBOSE
840                 fprintf(stderr,"    resolving field in class...\n");
841 #endif
842
843         fi = class_resolvefield(container,
844                                                         ref->fieldref->name,ref->fieldref->descriptor,
845                                                         referer,true);
846         if (!fi) {
847                 if (mode == resolveLazy) {
848                         /* The field does not exist. But since we were called lazily, */
849                         /* this error must not be reported now. (It will be reported   */
850                         /* if eager resolving of this field is ever tried.)           */
851
852                         *exceptionptr = NULL;
853                         return true; /* be lazy */
854                 }
855                 
856                 return false; /* exception */
857         }
858
859 #ifdef ENABLE_VERIFIER
860
861         /* { the field reference has been resolved } */
862         declarer = fi->class;
863         assert(declarer);
864         assert(declarer->state & CLASS_LOADED);
865         assert(declarer->state & CLASS_LINKED);
866
867 #ifdef RESOLVE_VERBOSE
868                 fprintf(stderr,"    checking static...\n");
869 #endif
870
871         /* check static */
872
873         if (((fi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {
874                 /* a static field is accessed via an instance, or vice versa */
875                 *exceptionptr = new_exception_message(string_java_lang_IncompatibleClassChangeError,
876                                 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
877                                                          : "instance field accessed without instance");
878                 return false; /* exception */
879         }
880
881         /* for non-static accesses we have to check the constraints on the */
882         /* instance type */
883
884         if (!(ref->flags & RESOLVE_STATIC)) {
885 #ifdef RESOLVE_VERBOSE
886                 fprintf(stderr,"    checking instance types...\n");
887 #endif
888
889                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
890                                                                                    &(ref->instancetypes),
891                                                                                    CLASSREF_OR_CLASSINFO(container),
892                                                                                    false, mode, resolveLinkageError,
893                                                                                    &checked))
894                 {
895                         return false; /* exception */
896                 }
897
898                 if (!checked)
899                         return true; /* be lazy */
900         }
901
902 #ifdef RESOLVE_VERBOSE
903         fprintf(stderr,"    checking instance types...done\n");
904 #endif
905
906         fieldtyperef = ref->fieldref->parseddesc.fd->classref;
907
908         /* for PUT* instructions we have to check the constraints on the value type */
909         if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
910 #ifdef RESOLVE_VERBOSE
911                 fprintf(stderr,"    checking value constraints...\n");
912 #endif
913                 assert(fieldtyperef);
914                 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
915                         /* check subtype constraints */
916                         if (!resolve_and_check_subtype_set(referer, ref->referermethod,
917                                                                                            &(ref->valueconstraints),
918                                                                                            CLASSREF_OR_CLASSINFO(fieldtyperef),
919                                                                                            false, mode, resolveLinkageError,
920                                                                                            &checked))
921                         {
922                                 return false; /* exception */
923                         }
924                         if (!checked)
925                                 return true; /* be lazy */
926                 }
927         }
928                                                                            
929         /* check access rights */
930 #ifdef RESOLVE_VERBOSE
931         fprintf(stderr,"    checking access rights...\n");
932 #endif
933         if (!access_is_accessible_member(referer,declarer,fi->flags)) {
934                 int msglen;
935                 char *message;
936
937                 msglen = utf_strlen(declarer->name) + utf_strlen(fi->name) + utf_strlen(referer->name) + 100;
938                 message = MNEW(char,msglen);
939                 strcpy(message,"field is not accessible (");
940                 utf_sprint_classname(message+strlen(message),declarer->name);
941                 strcat(message,".");
942                 utf_sprint(message+strlen(message),fi->name);
943                 strcat(message," from ");
944                 utf_sprint_classname(message+strlen(message),referer->name);
945                 strcat(message,")");
946                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
947                 MFREE(message,char,msglen);
948                 return false; /* exception */
949         }
950 #ifdef RESOLVE_VERBOSE
951         fprintf(stderr,"    checking access rights...done\n");
952         fprintf(stderr,"        declarer = ");
953         utf_fprint_classname(stderr,declarer->name); fputc('\n',stderr);
954         fprintf(stderr,"        referer = ");
955         utf_fprint_classname(stderr,referer->name); fputc('\n',stderr);
956 #endif
957
958         /* check protected access */
959         if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
960 #ifdef RESOLVE_VERBOSE
961                 fprintf(stderr,"    checking protected access...\n");
962 #endif
963                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
964                                                                                    &(ref->instancetypes),
965                                                                                    CLASSREF_OR_CLASSINFO(referer),
966                                                                                    false, mode,
967                                                                                    resolveIllegalAccessError, &checked))
968                 {
969                         return false; /* exception */
970                 }
971
972                 if (!checked)
973                         return true; /* be lazy */
974         }
975
976         /* impose loading constraint on field type */
977
978         if (fi->type == TYPE_ADR) {
979 #ifdef RESOLVE_VERBOSE
980                 fprintf(stderr,"    adding constraint...\n");
981 #endif
982                 assert(fieldtyperef);
983                 if (!classcache_add_constraint(declarer->classloader,
984                                                                            referer->classloader,
985                                                                            fieldtyperef->name))
986                         return false;
987         }
988 #endif /* ENABLE_VERIFIER */
989
990         /* succeed */
991 #ifdef RESOLVE_VERBOSE
992         fprintf(stderr,"    success.\n");
993 #endif
994         *result = fi;
995
996         return true;
997 }
998
999 /* resolve_field_eager *********************************************************
1000  
1001    Resolve an unresolved field reference eagerly.
1002   
1003    IN:
1004        ref..............struct containing the reference
1005    
1006    RETURN VALUE:
1007        fieldinfo * to the field, or
1008            NULL if an exception has been thrown
1009    
1010 *******************************************************************************/
1011
1012 fieldinfo * resolve_field_eager(unresolved_field *ref)
1013 {
1014         fieldinfo *fi;
1015
1016         if (!resolve_field(ref,resolveEager,&fi))
1017                 return NULL;
1018
1019         return fi;
1020 }
1021
1022 /******************************************************************************/
1023 /* METHOD RESOLUTION                                                          */
1024 /******************************************************************************/
1025
1026 /* resolve_method **************************************************************
1027  
1028    Resolve an unresolved method reference
1029   
1030    IN:
1031        ref..............struct containing the reference
1032        mode.............mode of resolution:
1033                             resolveLazy...only resolve if it does not
1034                                           require loading classes
1035                             resolveEager..load classes if necessary
1036   
1037    OUT:
1038        *result..........set to the result of resolution, or to NULL if
1039                         the reference has not been resolved
1040                         In the case of an exception, *result is
1041                         guaranteed to be set to NULL.
1042   
1043    RETURN VALUE:
1044        true.............everything ok 
1045                         (*result may still be NULL for resolveLazy)
1046        false............an exception has been thrown
1047    
1048 *******************************************************************************/
1049
1050 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1051 {
1052         classinfo *referer;
1053         classinfo *container;
1054         classinfo *declarer;
1055         methodinfo *mi;
1056         typedesc *paramtypes;
1057         int instancecount;
1058         int i;
1059         bool checked;
1060         
1061         assert(ref);
1062         assert(result);
1063         assert(mode == resolveLazy || mode == resolveEager);
1064
1065 #ifdef RESOLVE_VERBOSE
1066         unresolved_method_debug_dump(ref,stderr);
1067 #endif
1068
1069         *result = NULL;
1070
1071         /* the class containing the reference */
1072         referer = ref->methodref->classref->referer;
1073         assert(referer);
1074
1075         /* first we must resolve the class containg the method */
1076         if (!resolve_class_from_name(referer,ref->referermethod,
1077                                            ref->methodref->classref->name,mode,true,true,&container))
1078         {
1079                 /* the class reference could not be resolved */
1080                 return false; /* exception */
1081         }
1082         if (!container)
1083                 return true; /* be lazy */
1084
1085         assert(container);
1086         assert(container->state & CLASS_LINKED);
1087
1088         /* now we must find the declaration of the method in `container`
1089          * or one of its superclasses */
1090
1091         if (container->flags & ACC_INTERFACE) {
1092                 mi = class_resolveinterfacemethod(container,
1093                                                                               ref->methodref->name,
1094                                                                                   ref->methodref->descriptor,
1095                                                                               referer, true);
1096
1097         } else {
1098                 mi = class_resolveclassmethod(container,
1099                                                                           ref->methodref->name,
1100                                                                           ref->methodref->descriptor,
1101                                                                           referer, true);
1102         }
1103
1104         if (!mi) {
1105                 if (mode == resolveLazy) {
1106                         /* The method does not exist. But since we were called lazily, */
1107                         /* this error must not be reported now. (It will be reported   */
1108                         /* if eager resolving of this method is ever tried.)           */
1109
1110                         *exceptionptr = NULL;
1111                         return true; /* be lazy */
1112                 }
1113                 
1114                 return false; /* exception */ /* XXX set exceptionptr? */
1115         }
1116
1117 #ifdef ENABLE_VERIFIER
1118
1119 #ifdef RESOLVE_VERBOSE
1120         fprintf(stderr,"    flags: %02x\n",mi->flags);
1121 #endif
1122         /* { the method reference has been resolved } */
1123
1124         declarer = mi->class;
1125         assert(declarer);
1126         assert(referer->state & CLASS_LINKED);
1127
1128         /* checks for INVOKESPECIAL:                                       */
1129         /* for <init> and methods of the current class we don't need any   */
1130         /* special checks. Otherwise we must verify that the called method */
1131         /* belongs to a super class of the current class                   */
1132         if (((ref->flags & RESOLVE_SPECIAL) != 0) 
1133                 && referer != declarer 
1134                 && mi->name != utf_init) 
1135         {
1136                 /* check that declarer is a super class of the current class   */
1137                 if (!class_issubclass(referer,declarer)) {
1138                         *exceptionptr = new_verifyerror(ref->referermethod,
1139                                         "INVOKESPECIAL calling non-super class method");
1140                         return false;
1141                 }
1142
1143                 /* if the referer has ACC_SUPER set, we must do the special    */
1144                 /* lookup starting with the direct super class of referer      */
1145                 if ((referer->flags & ACC_SUPER) != 0) {
1146                         mi = class_resolvemethod(referer->super.cls,
1147                                                                          ref->methodref->name,
1148                                                                          ref->methodref->descriptor);
1149                         if (!mi) {
1150                                 /* the spec calls for an AbstractMethodError in this case */
1151                                 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
1152                                 return false;
1153                         }
1154                         declarer = mi->class;
1155                 }
1156         }
1157
1158         /* check static */
1159
1160         if (((mi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {
1161                 /* a static method is accessed via an instance, or vice versa */
1162                 *exceptionptr =
1163                         new_exception_message(string_java_lang_IncompatibleClassChangeError,
1164                                 (mi->flags & ACC_STATIC) ? "static method called via instance"
1165                                                          : "instance method called without instance");
1166                 return false;
1167         }
1168
1169         /* have the method params already been parsed? no, do it. */
1170
1171         if (!mi->parseddesc->params)
1172                 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1173                         return false;
1174                 
1175         /* for non-static methods we have to check the constraints on the         */
1176         /* instance type                                                          */
1177
1178         if (!(ref->flags & RESOLVE_STATIC)) {
1179                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1180                                                                                    &(ref->instancetypes),
1181                                                                                    CLASSREF_OR_CLASSINFO(container),
1182                                                                                    false,
1183                                                                                    mode,
1184                                                                                    resolveLinkageError,&checked))
1185                 {
1186                         return false; /* exception */
1187                 }
1188                 if (!checked)
1189                         return true; /* be lazy */
1190                 instancecount = 1;
1191         }
1192         else {
1193                 instancecount = 0;
1194         }
1195
1196         /* check subtype constraints for TYPE_ADR parameters */
1197
1198         assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
1199         paramtypes = mi->parseddesc->paramtypes;
1200         
1201         for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
1202                 if (paramtypes[i+instancecount].type == TYPE_ADR) {
1203                         if (ref->paramconstraints) {
1204                                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1205                                                         ref->paramconstraints + i,
1206                                                         CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1207                                                         false,
1208                                                         mode,
1209                                                         resolveLinkageError,&checked))
1210                                 {
1211                                         return false; /* exception */
1212                                 }
1213                                 if (!checked)
1214                                         return true; /* be lazy */
1215                         }
1216                 }
1217         }
1218
1219         /* check access rights */
1220
1221         if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1222                 int msglen;
1223                 char *message;
1224
1225                 msglen = utf_strlen(declarer->name) + utf_strlen(mi->name) + 
1226                         utf_strlen(mi->descriptor) + utf_strlen(referer->name) + 100;
1227                 message = MNEW(char,msglen);
1228                 strcpy(message,"method is not accessible (");
1229                 utf_sprint_classname(message+strlen(message),declarer->name);
1230                 strcat(message,".");
1231                 utf_sprint(message+strlen(message),mi->name);
1232                 utf_sprint(message+strlen(message),mi->descriptor);
1233                 strcat(message," from ");
1234                 utf_sprint_classname(message+strlen(message),referer->name);
1235                 strcat(message,")");
1236                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
1237                 MFREE(message,char,msglen);
1238                 return false; /* exception */
1239         }
1240
1241         /* check protected access */
1242
1243         if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1244         {
1245                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1246                                                                                    &(ref->instancetypes),
1247                                                                                    CLASSREF_OR_CLASSINFO(referer),
1248                                                                                    false,
1249                                                                                    mode,
1250                                                                                    resolveIllegalAccessError,&checked))
1251                 {
1252                         return false; /* exception */
1253                 }
1254                 if (!checked)
1255                         return true; /* be lazy */
1256         }
1257
1258         /* impose loading constraints on parameters (including instance) */
1259
1260         paramtypes = mi->parseddesc->paramtypes;
1261
1262         for (i = 0; i < mi->parseddesc->paramcount; i++) {
1263                 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1264                         utf *name;
1265                         
1266                         if (i < instancecount) {
1267                                 /* The type of the 'this' pointer is the class containing */
1268                                 /* the method definition. Since container is the same as, */
1269                                 /* or a subclass of declarer, we also constrain declarer  */
1270                                 /* by transitivity of loading constraints.                */
1271                                 name = container->name;
1272                         }
1273                         else {
1274                                 name = paramtypes[i].classref->name;
1275                         }
1276                         
1277                         /* The caller (referer) and the callee (container) must agree */
1278                         /* on the types of the parameters.                            */
1279                         if (!classcache_add_constraint(referer->classloader,
1280                                                                                    container->classloader, name))
1281                                 return false; /* exception */
1282                 }
1283         }
1284
1285         /* impose loading constraint onto return type */
1286
1287         if (ref->methodref->parseddesc.md->returntype.type == TYPE_ADR) {
1288                 /* The caller (referer) and the callee (container) must agree */
1289                 /* on the return type.                                        */
1290                 if (!classcache_add_constraint(referer->classloader,container->classloader,
1291                                 ref->methodref->parseddesc.md->returntype.classref->name))
1292                         return false; /* exception */
1293         }
1294
1295 #endif /* ENABLE_VERIFIER */
1296
1297         /* succeed */
1298         *result = mi;
1299         return true;
1300 }
1301
1302 /* resolve_method_eager ********************************************************
1303  
1304    Resolve an unresolved method reference eagerly.
1305   
1306    IN:
1307        ref..............struct containing the reference
1308    
1309    RETURN VALUE:
1310        methodinfo * to the method, or
1311            NULL if an exception has been thrown
1312    
1313 *******************************************************************************/
1314
1315 methodinfo * resolve_method_eager(unresolved_method *ref)
1316 {
1317         methodinfo *mi;
1318
1319         if (!resolve_method(ref,resolveEager,&mi))
1320                 return NULL;
1321
1322         return mi;
1323 }
1324
1325 /******************************************************************************/
1326 /* CREATING THE DATA STRUCTURES                                               */
1327 /******************************************************************************/
1328
1329 #ifdef ENABLE_VERIFIER
1330 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
1331                                                                                                  methodinfo *refmethod,
1332                                                                                                  unresolved_subtype_set *stset,
1333                                                                                                  typeinfo *tinfo,
1334                                                                                                  constant_classref *declaredtype)
1335 {
1336         int count;
1337         int i;
1338         
1339         assert(stset);
1340         assert(tinfo);
1341
1342 #ifdef RESOLVE_VERBOSE
1343         fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
1344 #ifdef TYPEINFO_DEBUG
1345         typeinfo_print(stderr,tinfo,4);
1346 #endif
1347         fprintf(stderr,"    declared type:");utf_fprint(stderr,declaredtype->name);
1348         fprintf(stderr,"\n");
1349 #endif
1350
1351         if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
1352                 *exceptionptr = new_verifyerror(refmethod,
1353                                 "Invalid use of returnAddress");
1354                 return false;
1355         }
1356
1357         if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
1358                 *exceptionptr = new_verifyerror(refmethod,
1359                                 "Invalid use of uninitialized object");
1360                 return false;
1361         }
1362
1363         /* the nulltype is always assignable (XXX for reversed?) */
1364         if (TYPEINFO_IS_NULLTYPE(*tinfo))
1365                 goto empty_set;
1366
1367         /* every type is assignable to (BOOTSTRAP)java.lang.Object */
1368         if (declaredtype->name == utf_java_lang_Object
1369                         && referer->classloader == NULL)
1370         {
1371                 goto empty_set;
1372         }
1373
1374         if (tinfo->merged) {
1375                 count = tinfo->merged->count;
1376                 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
1377                 for (i=0; i<count; ++i) {
1378                         classref_or_classinfo c = tinfo->merged->list[i];
1379                         if (tinfo->dimension > 0) {
1380                                 /* a merge of array types */
1381                                 /* the merged list contains the possible _element_ types, */
1382                                 /* so we have to create array types with these elements.  */
1383                                 if (IS_CLASSREF(c)) {
1384                                         c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
1385                                 }
1386                                 else {
1387                                         c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
1388                                 }
1389                         }
1390                         stset->subtyperefs[i] = c;
1391                 }
1392                 stset->subtyperefs[count].any = NULL; /* terminate */
1393         }
1394         else {
1395                 if ((IS_CLASSREF(tinfo->typeclass)
1396                                         ? tinfo->typeclass.ref->name 
1397                                         : tinfo->typeclass.cls->name) == declaredtype->name)
1398                 {
1399                         /* the class names are the same */
1400                     /* equality is guaranteed by the loading constraints */
1401                         goto empty_set;
1402                 }
1403                 else {
1404                         stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
1405                         stset->subtyperefs[0] = tinfo->typeclass;
1406                         stset->subtyperefs[1].any = NULL; /* terminate */
1407                 }
1408         }
1409
1410         return true;
1411
1412 empty_set:
1413         UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
1414         return true;
1415 }
1416 #endif /* ENABLE_VERIFIER */
1417
1418 /* create_unresolved_class *****************************************************
1419  
1420    Create an unresolved_class struct for the given class reference
1421   
1422    IN:
1423            refmethod........the method triggering the resolution (if any)
1424            classref.........the class reference
1425            valuetype........value type to check against the resolved class
1426                                                 may be NULL, if no typeinfo is available
1427
1428    RETURN VALUE:
1429        a pointer to a new unresolved_class struct, or
1430            NULL if an exception has been thrown
1431
1432 *******************************************************************************/
1433
1434 #ifdef ENABLE_VERIFIER
1435 unresolved_class * create_unresolved_class(methodinfo *refmethod,
1436                                                                                    constant_classref *classref,
1437                                                                                    typeinfo *valuetype)
1438 {
1439         unresolved_class *ref;
1440         
1441 #ifdef RESOLVE_VERBOSE
1442         fprintf(stderr,"create_unresolved_class\n");
1443         fprintf(stderr,"    referer: ");utf_fprint(stderr,classref->referer->name);fputc('\n',stderr);
1444         if (refmethod) {
1445                 fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1446                 fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1447         }
1448         fprintf(stderr,"    name   : ");utf_fprint(stderr,classref->name);fputc('\n',stderr);
1449 #endif
1450
1451         ref = NEW(unresolved_class);
1452         ref->classref = classref;
1453         ref->referermethod = refmethod;
1454
1455         if (valuetype) {
1456                 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
1457                                         &(ref->subtypeconstraints),valuetype,classref))
1458                         return NULL;
1459         }
1460         else {
1461                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
1462         }
1463
1464         return ref;
1465 }
1466 #endif /* ENABLE_VERIFIER */
1467
1468 /* create_unresolved_field *****************************************************
1469  
1470    Create an unresolved_field struct for the given field access instruction
1471   
1472    IN:
1473        referer..........the class containing the reference
1474            refmethod........the method triggering the resolution (if any)
1475            iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
1476
1477    RETURN VALUE:
1478        a pointer to a new unresolved_field struct, or
1479            NULL if an exception has been thrown
1480
1481 *******************************************************************************/
1482
1483 unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refmethod,
1484                                                                                    instruction *iptr)
1485 {
1486         unresolved_field *ref;
1487         constant_FMIref *fieldref = NULL;
1488
1489 #ifdef RESOLVE_VERBOSE
1490         fprintf(stderr,"create_unresolved_field\n");
1491         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1492         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1493         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1494 #endif
1495
1496         ref = NEW(unresolved_field);
1497         ref->flags = 0;
1498         ref->referermethod = refmethod;
1499         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
1500
1501         switch (iptr[0].opc) {
1502                 case ICMD_PUTFIELD:
1503                         ref->flags |= RESOLVE_PUTFIELD;
1504                         fieldref = (constant_FMIref *) iptr[0].val.a;
1505                         break;
1506
1507                 case ICMD_PUTFIELDCONST:
1508                         ref->flags |= RESOLVE_PUTFIELD;
1509                         fieldref = (constant_FMIref *) iptr[1].val.a;
1510                         break;
1511
1512                 case ICMD_PUTSTATIC:
1513                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
1514                         fieldref = (constant_FMIref *) iptr[0].val.a;
1515                         break;
1516
1517                 case ICMD_PUTSTATICCONST:
1518                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
1519                         fieldref = (constant_FMIref *) iptr[1].val.a;
1520                         break;
1521
1522                 case ICMD_GETFIELD:
1523                         fieldref = (constant_FMIref *) iptr[0].val.a;
1524                         break;
1525                         
1526                 case ICMD_GETSTATIC:
1527                         ref->flags |= RESOLVE_STATIC;
1528                         fieldref = (constant_FMIref *) iptr[0].val.a;
1529                         break;
1530         }
1531         
1532         assert(fieldref);
1533
1534 #ifdef RESOLVE_VERBOSE
1535         fprintf(stderr,"    class  : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
1536         fprintf(stderr,"    name   : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
1537         fprintf(stderr,"    desc   : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
1538         fprintf(stderr,"    type   : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
1539         fputc('\n',stderr);
1540         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1541 #endif
1542
1543         ref->fieldref = fieldref;
1544
1545         return ref;
1546 }
1547
1548 /* constrain_unresolved_field **************************************************
1549  
1550    Record subtype constraints for a field access.
1551   
1552    IN:
1553        ref..............the unresolved_field structure of the access
1554        referer..........the class containing the reference
1555            refmethod........the method triggering the resolution (if any)
1556            iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
1557            stack............the input stack of the instruction
1558
1559    RETURN VALUE:
1560        true.............everything ok
1561            false............an exception has been thrown
1562
1563 *******************************************************************************/
1564
1565 #ifdef ENABLE_VERIFIER
1566 bool constrain_unresolved_field(unresolved_field *ref,
1567                                                             classinfo *referer, methodinfo *refmethod,
1568                                                             instruction *iptr,
1569                                                             stackelement *stack)
1570 {
1571         constant_FMIref *fieldref;
1572         stackelement *instanceslot = NULL;
1573         int type;
1574         typeinfo tinfo;
1575         typeinfo *tip = NULL;
1576         typedesc *fd;
1577
1578         assert(ref);
1579
1580         fieldref = ref->fieldref;
1581         assert(fieldref);
1582
1583 #ifdef RESOLVE_VERBOSE
1584         fprintf(stderr,"constrain_unresolved_field\n");
1585         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1586         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1587         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1588         fprintf(stderr,"    class  : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
1589         fprintf(stderr,"    name   : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
1590         fprintf(stderr,"    desc   : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
1591         fprintf(stderr,"    type   : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
1592         fputc('\n',stderr);
1593         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1594 #endif
1595
1596         switch (iptr[0].opc) {
1597                 case ICMD_PUTFIELD:
1598                         instanceslot = stack->prev;
1599                         tip = &(stack->typeinfo);
1600                         break;
1601
1602                 case ICMD_PUTFIELDCONST:
1603                         instanceslot = stack;
1604                         break;
1605
1606                 case ICMD_PUTSTATIC:
1607                         tip = &(stack->typeinfo);
1608                         break;
1609
1610                 case ICMD_GETFIELD:
1611                         instanceslot = stack;
1612                         break;
1613         }
1614         
1615         assert(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
1616         fd = fieldref->parseddesc.fd;
1617         assert(fd);
1618
1619         /* record subtype constraints for the instance type, if any */
1620         if (instanceslot) {
1621                 typeinfo *insttip;
1622
1623                 /* The instanceslot must contain a reference to a non-array type */
1624                 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
1625                         *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1626                         return false;
1627                 }
1628                 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
1629                         *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on array");
1630                         return false;
1631                 }
1632                 
1633                 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && 
1634                                 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1635                 {
1636                         /* The instruction writes a field in an uninitialized object. */
1637                         /* This is only allowed when a field of an uninitialized 'this' object is */
1638                         /* written inside an initialization method                                */
1639                         
1640                         classinfo *initclass;
1641                         instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1642
1643                         if (ins != NULL) {
1644                                 *exceptionptr = new_verifyerror(refmethod,"accessing field of uninitialized object");
1645                                 return false;
1646                         }
1647                         /* XXX check that class of field == refmethod->class */
1648                         initclass = refmethod->class; /* XXX classrefs */
1649                         assert(initclass->state & CLASS_LOADED);
1650                         assert(initclass->state & CLASS_LINKED);
1651
1652                         typeinfo_init_classinfo(&tinfo,initclass);
1653                         insttip = &tinfo;
1654                 }
1655                 else {
1656                         insttip = &(instanceslot->typeinfo);
1657                 }
1658                 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1659                                         &(ref->instancetypes),insttip,fieldref->classref))
1660                         return false;
1661         }
1662         else {
1663                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1664         }
1665         
1666         /* record subtype constraints for the value type, if any */
1667         type = fd->type;
1668         if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
1669                 if (!tip) {
1670                         /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
1671                         tip = &tinfo;
1672                         if (INSTRUCTION_PUTCONST_VALUE_ADR(iptr)) {
1673                                 assert(class_java_lang_String);
1674                                 assert(class_java_lang_String->state & CLASS_LOADED);
1675                                 assert(class_java_lang_String->state & CLASS_LINKED);
1676                                 typeinfo_init_classinfo(&tinfo,class_java_lang_String);
1677                         }
1678                         else
1679                                 TYPEINFO_INIT_NULLTYPE(tinfo);
1680                 }
1681                 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1682                                         &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref))
1683                         return false;
1684         }
1685         else {
1686                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
1687         }
1688
1689         return true;
1690 }
1691 #endif /* ENABLE_VERIFIER */
1692
1693 /* create_unresolved_method ****************************************************
1694  
1695    Create an unresolved_method struct for the given method invocation
1696   
1697    IN:
1698        referer..........the class containing the reference
1699            refmethod........the method triggering the resolution (if any)
1700            iptr.............the INVOKE* instruction
1701
1702    RETURN VALUE:
1703        a pointer to a new unresolved_method struct, or
1704            NULL if an exception has been thrown
1705
1706 *******************************************************************************/
1707
1708 unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *refmethod,
1709                                                                                          instruction *iptr)
1710 {
1711         unresolved_method *ref;
1712         constant_FMIref *methodref;
1713         bool staticmethod;
1714
1715         methodref = (constant_FMIref *) iptr[0].val.a;
1716         assert(methodref);
1717         staticmethod = (iptr[0].opc == ICMD_INVOKESTATIC);
1718
1719 #ifdef RESOLVE_VERBOSE
1720         fprintf(stderr,"create_unresolved_method\n");
1721         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1722         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1723         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1724         fprintf(stderr,"    class  : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1725         fprintf(stderr,"    name   : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1726         fprintf(stderr,"    desc   : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1727         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1728 #endif
1729
1730         /* allocate params if necessary */
1731         if (!methodref->parseddesc.md->params)
1732                 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
1733                                         (staticmethod) ? ACC_STATIC : ACC_NONE))
1734                         return NULL;
1735
1736         /* create the data structure */
1737         ref = NEW(unresolved_method);
1738         ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
1739                            | ((iptr[0].opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
1740         ref->referermethod = refmethod;
1741         ref->methodref = methodref;
1742         ref->paramconstraints = NULL;
1743         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1744
1745         return ref;
1746 }
1747
1748 /* constrain_unresolved_method *************************************************
1749  
1750    Record subtype constraints for the arguments of a method call.
1751   
1752    IN:
1753        ref..............the unresolved_method structure of the call
1754        referer..........the class containing the reference
1755            refmethod........the method triggering the resolution (if any)
1756            iptr.............the INVOKE* instruction
1757            stack............the input stack of the instruction
1758
1759    RETURN VALUE:
1760        true.............everything ok
1761            false............an exception has been thrown
1762
1763 *******************************************************************************/
1764
1765 #ifdef ENABLE_VERIFIER
1766 bool constrain_unresolved_method(unresolved_method *ref,
1767                                                                  classinfo *referer, methodinfo *refmethod,
1768                                                                  instruction *iptr,
1769                                                                  stackelement *stack)
1770 {
1771         constant_FMIref *methodref;
1772         stackelement *instanceslot = NULL;
1773         stackelement *param;
1774         methoddesc *md;
1775         typeinfo tinfo;
1776         int i,j;
1777         int type;
1778         int instancecount;
1779
1780         assert(ref);
1781         methodref = ref->methodref;
1782         assert(methodref);
1783         md = methodref->parseddesc.md;
1784         assert(md);
1785         assert(md->params != NULL);
1786
1787 #ifdef RESOLVE_VERBOSE
1788         fprintf(stderr,"constrain_unresolved_method\n");
1789         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1790         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1791         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1792         fprintf(stderr,"    class  : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1793         fprintf(stderr,"    name   : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1794         fprintf(stderr,"    desc   : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1795         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1796 #endif
1797
1798         if ((ref->flags & RESOLVE_STATIC) == 0) {
1799                 /* find the instance slot under all the parameter slots on the stack */
1800                 instanceslot = stack;
1801                 for (i=1; i<md->paramcount; ++i)
1802                         instanceslot = instanceslot->prev;
1803                 instancecount = 1;
1804         }
1805         else {
1806                 instancecount = 0;
1807         }
1808         
1809         assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
1810
1811         /* record subtype constraints for the instance type, if any */
1812         if (instanceslot) {
1813                 typeinfo *tip;
1814                 
1815                 assert(instanceslot->type == TYPE_ADR);
1816                 
1817                 if (iptr[0].opc == ICMD_INVOKESPECIAL && 
1818                                 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1819                 {   /* XXX clean up */
1820                         instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1821                         classref_or_classinfo initclass = (ins) ? CLASSREF_OR_CLASSINFO(ins[-1].target)
1822                                                                                  : CLASSREF_OR_CLASSINFO(refmethod->class);
1823                         tip = &tinfo;
1824                         if (!typeinfo_init_class(tip,initclass))
1825                                 return false;
1826                 }
1827                 else {
1828                         tip = &(instanceslot->typeinfo);
1829                 }
1830                 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1831                                         &(ref->instancetypes),tip,methodref->classref))
1832                         return false;
1833         }
1834         
1835         /* record subtype constraints for the parameter types, if any */
1836         param = stack;
1837         for (i=md->paramcount-1-instancecount; i>=0; --i, param=param->prev) {
1838                 type = md->paramtypes[i+instancecount].type;
1839
1840                 assert(param);
1841                 assert(type == param->type);
1842
1843                 if (type == TYPE_ADR) {
1844                         if (!ref->paramconstraints) {
1845                                 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
1846                                 for (j=md->paramcount-1-instancecount; j>i; --j)
1847                                         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
1848                         }
1849                         assert(ref->paramconstraints);
1850                         if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1851                                                 ref->paramconstraints + i,&(param->typeinfo),
1852                                                 md->paramtypes[i+instancecount].classref))
1853                                 return false;
1854                 }
1855                 else {
1856                         if (ref->paramconstraints)
1857                                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
1858                 }
1859         }
1860
1861         return true;
1862 }
1863 #endif /* ENABLE_VERIFIER */
1864
1865 /******************************************************************************/
1866 /* FREEING MEMORY                                                             */
1867 /******************************************************************************/
1868
1869 #ifdef ENABLE_VERIFIER
1870 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
1871 {
1872         if (list) {
1873                 classref_or_classinfo *p = list;
1874
1875                 /* this is silly. we *only* need to count the elements for MFREE */
1876                 while ((p++)->any)
1877                         ;
1878                 MFREE(list,classref_or_classinfo,(p - list));
1879         }
1880 }
1881 #endif /* ENABLE_VERIFIER */
1882
1883 /* unresolved_class_free *******************************************************
1884  
1885    Free the memory used by an unresolved_class
1886   
1887    IN:
1888        ref..............the unresolved_class
1889
1890 *******************************************************************************/
1891
1892 void unresolved_class_free(unresolved_class *ref)
1893 {
1894         assert(ref);
1895
1896 #ifdef ENABLE_VERIFIER
1897         unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
1898 #endif
1899         FREE(ref,unresolved_class);
1900 }
1901
1902 /* unresolved_field_free *******************************************************
1903  
1904    Free the memory used by an unresolved_field
1905   
1906    IN:
1907        ref..............the unresolved_field
1908
1909 *******************************************************************************/
1910
1911 void unresolved_field_free(unresolved_field *ref)
1912 {
1913         assert(ref);
1914
1915 #ifdef ENABLE_VERIFIER
1916         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1917         unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
1918 #endif
1919         FREE(ref,unresolved_field);
1920 }
1921
1922 /* unresolved_method_free ******************************************************
1923  
1924    Free the memory used by an unresolved_method
1925   
1926    IN:
1927        ref..............the unresolved_method
1928
1929 *******************************************************************************/
1930
1931 void unresolved_method_free(unresolved_method *ref)
1932 {
1933         assert(ref);
1934
1935 #ifdef ENABLE_VERIFIER
1936         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1937         if (ref->paramconstraints) {
1938                 int i;
1939                 int count = ref->methodref->parseddesc.md->paramcount;
1940
1941                 for (i=0; i<count; ++i)
1942                         unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
1943                 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
1944         }
1945 #endif
1946         FREE(ref,unresolved_method);
1947 }
1948
1949 #ifndef NDEBUG
1950 /******************************************************************************/
1951 /* DEBUG DUMPS                                                                */
1952 /******************************************************************************/
1953
1954 /* unresolved_subtype_set_debug_dump *******************************************
1955  
1956    Print debug info for unresolved_subtype_set to stream
1957   
1958    IN:
1959        stset............the unresolved_subtype_set
1960            file.............the stream
1961
1962 *******************************************************************************/
1963
1964 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
1965 {
1966         classref_or_classinfo *p;
1967         
1968         if (SUBTYPESET_IS_EMPTY(*stset)) {
1969                 fprintf(file,"        (empty)\n");
1970         }
1971         else {
1972                 p = stset->subtyperefs;
1973                 for (;p->any; ++p) {
1974                         if (IS_CLASSREF(*p)) {
1975                                 fprintf(file,"        ref: ");
1976                                 utf_fprint(file,p->ref->name);
1977                         }
1978                         else {
1979                                 fprintf(file,"        cls: ");
1980                                 utf_fprint(file,p->cls->name);
1981                         }
1982                         fputc('\n',file);
1983                 }
1984         }
1985 }
1986
1987 /* unresolved_class_debug_dump *************************************************
1988  
1989    Print debug info for unresolved_class to stream
1990   
1991    IN:
1992        ref..............the unresolved_class
1993            file.............the stream
1994
1995 *******************************************************************************/
1996
1997 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
1998 {
1999         fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2000         if (ref) {
2001                 fprintf(file,"    referer   : ");
2002                 utf_fprint(file,ref->classref->referer->name); fputc('\n',file);
2003                 fprintf(file,"    refmethod : ");
2004                 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2005                 fprintf(file,"    refmethodd: ");
2006                 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2007                 fprintf(file,"    classname : ");
2008                 utf_fprint(file,ref->classref->name); fputc('\n',file);
2009                 fprintf(file,"    subtypeconstraints:\n");
2010                 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2011         }
2012 }
2013
2014 /* unresolved_field_debug_dump *************************************************
2015  
2016    Print debug info for unresolved_field to stream
2017   
2018    IN:
2019        ref..............the unresolved_field
2020            file.............the stream
2021
2022 *******************************************************************************/
2023
2024 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2025 {
2026         fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2027         if (ref) {
2028                 fprintf(file,"    referer   : ");
2029                 utf_fprint(file,ref->fieldref->classref->referer->name); fputc('\n',file);
2030                 fprintf(file,"    refmethod : ");
2031                 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2032                 fprintf(file,"    refmethodd: ");
2033                 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2034                 fprintf(file,"    classname : ");
2035                 utf_fprint(file,ref->fieldref->classref->name); fputc('\n',file);
2036                 fprintf(file,"    name      : ");
2037                 utf_fprint(file,ref->fieldref->name); fputc('\n',file);
2038                 fprintf(file,"    descriptor: ");
2039                 utf_fprint(file,ref->fieldref->descriptor); fputc('\n',file);
2040                 fprintf(file,"    parseddesc: ");
2041                 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2042                 fprintf(file,"    flags     : %04x\n",ref->flags);
2043                 fprintf(file,"    instancetypes:\n");
2044                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2045                 fprintf(file,"    valueconstraints:\n");
2046                 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2047         }
2048 }
2049
2050 /* unresolved_method_debug_dump ************************************************
2051  
2052    Print debug info for unresolved_method to stream
2053   
2054    IN:
2055        ref..............the unresolved_method
2056            file.............the stream
2057
2058 *******************************************************************************/
2059
2060 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2061 {
2062         int i;
2063
2064         fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2065         if (ref) {
2066                 fprintf(file,"    referer   : ");
2067                 utf_fprint(file,ref->methodref->classref->referer->name); fputc('\n',file);
2068                 fprintf(file,"    refmethod : ");
2069                 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2070                 fprintf(file,"    refmethodd: ");
2071                 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2072                 fprintf(file,"    classname : ");
2073                 utf_fprint(file,ref->methodref->classref->name); fputc('\n',file);
2074                 fprintf(file,"    name      : ");
2075                 utf_fprint(file,ref->methodref->name); fputc('\n',file);
2076                 fprintf(file,"    descriptor: ");
2077                 utf_fprint(file,ref->methodref->descriptor); fputc('\n',file);
2078                 fprintf(file,"    parseddesc: ");
2079                 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2080                 fprintf(file,"    flags     : %04x\n",ref->flags);
2081                 fprintf(file,"    instancetypes:\n");
2082                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2083                 fprintf(file,"    paramconstraints:\n");
2084                 if (ref->paramconstraints) {
2085                         for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2086                                 fprintf(file,"      param %d:\n",i);
2087                                 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2088                         }
2089                 } 
2090                 else {
2091                         fprintf(file,"      (empty)\n");
2092                 }
2093         }
2094 }
2095 #endif
2096
2097 /*
2098  * These are local overrides for various environment variables in Emacs.
2099  * Please do not remove this and leave it at the end of the file, where
2100  * Emacs will automagically detect them.
2101  * ---------------------------------------------------------------------
2102  * Local variables:
2103  * mode: c
2104  * indent-tabs-mode: t
2105  * c-basic-offset: 4
2106  * tab-width: 4
2107  * End:
2108  * vim:noexpandtab:sw=4:ts=4:
2109  */
2110