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