split create_unresolved_* functions in create_* and constrain_* parts
[cacao.git] / src / vm / resolve.c
1 /* src/vm/resolve.c - resolving classes/interfaces/fields/methods
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Edwin Steiner
28
29    Changes: Christan Thalinger
30
31    $Id: resolve.c 2738 2005-06-18 16:37:34Z edwin $
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 #ifndef NDEBUG
58 #define RESOLVE_DEBUG
59 #endif
60
61 #ifdef RESOLVE_DEBUG
62 #define RESOLVE_ASSERT(cond)  assert(cond)
63 #else
64 #define RESOLVE_ASSERT(cond)
65 #endif
66
67 /******************************************************************************/
68 /* CLASS RESOLUTION                                                           */
69 /******************************************************************************/
70
71 /* resolve symbolic class reference -- see resolve.h */
72 bool
73 resolve_class_from_name(classinfo *referer,methodinfo *refmethod,
74                           utf *classname,
75                           resolve_mode_t mode,
76                           bool link,
77                           classinfo **result)
78 {
79         classinfo *cls = NULL;
80         char *utf_ptr;
81         int len;
82         
83         RESOLVE_ASSERT(result);
84         RESOLVE_ASSERT(referer);
85         RESOLVE_ASSERT(classname);
86         RESOLVE_ASSERT(mode == resolveLazy || mode == resolveEager);
87         
88         *result = NULL;
89
90 #ifdef RESOLVE_VERBOSE
91         fprintf(stderr,"resolve_class_from_name(");
92         utf_fprint(stderr,referer->name);
93         fprintf(stderr,",");
94         utf_fprint(stderr,classname);
95         fprintf(stderr,")\n");
96 #endif
97
98         /* lookup if this class has already been loaded */
99         cls = classcache_lookup(referer->classloader,classname);
100
101 #ifdef RESOLVE_VERBOSE
102         fprintf(stderr,"    lookup result: %p\n",(void*)cls);
103 #endif
104         
105         if (!cls) {
106                 /* resolve array types */
107                 if (classname->text[0] == '[') {
108                         utf_ptr = classname->text + 1;
109                         len = classname->blength - 1;
110                         /* classname is an array type name */
111                         switch (*utf_ptr) {
112                                 case 'L':
113                                         utf_ptr++;
114                                         len -= 2;
115                                         /* FALLTHROUGH */
116                                 case '[':
117                                         /* the component type is a reference type */
118                                         /* resolve the component type */
119                                         if (!resolve_class_from_name(referer,refmethod,
120                                                                            utf_new(utf_ptr,len),
121                                                                            mode,link,&cls))
122                                                 return false; /* exception */
123                                         if (!cls) {
124                                                 RESOLVE_ASSERT(mode == resolveLazy);
125                                                 return true; /* be lazy */
126                                         }
127                                         /* create the array class */
128                                         cls = class_array_of(cls,false);
129                                         if (!cls)
130                                                 return false; /* exception */
131                         }
132                 }
133                 else {
134                         /* the class has not been loaded, yet */
135                         if (mode == resolveLazy)
136                                 return true; /* be lazy */
137                 }
138
139 #ifdef RESOLVE_VERBOSE
140                 fprintf(stderr,"    loading...\n");
141 #endif
142
143                 /* load the class */
144                 if (!cls) {
145                         if (!(cls = load_class_from_classloader(classname,
146                                                                                                         referer->classloader)))
147                                 return false; /* exception */
148                 }
149         }
150
151         /* the class is now loaded */
152         RESOLVE_ASSERT(cls);
153         RESOLVE_ASSERT(cls->loaded);
154
155 #ifdef RESOLVE_VERBOSE
156         fprintf(stderr,"    checking access rights...\n");
157 #endif
158         
159         /* check access rights of referer to refered class */
160         if (!is_accessible_class(referer,cls)) {
161                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,
162                                 "class is not accessible XXX add message");
163                 return false; /* exception */
164         }
165
166         /* link the class if necessary */
167         if (link) {
168                 if (!cls->linked)
169                         if (!link_class(cls))
170                                 return false; /* exception */
171                 RESOLVE_ASSERT(cls->linked);
172         }
173
174         /* resolution succeeds */
175 #ifdef RESOLVE_VERBOSE
176         fprintf(stderr,"    success.\n");
177 #endif
178         *result = cls;
179         return true;
180 }
181
182 bool
183 resolve_classref(methodinfo *refmethod,
184                                  constant_classref *ref,
185                                  resolve_mode_t mode,
186                              bool link,
187                                  classinfo **result)
188 {
189         return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,link,result);
190 }
191
192 bool
193 resolve_classref_or_classinfo(methodinfo *refmethod,
194                                                           classref_or_classinfo cls,
195                                                           resolve_mode_t mode,
196                                                           bool link,
197                                                           classinfo **result)
198 {
199         classinfo *c;
200         
201         RESOLVE_ASSERT(cls.any);
202         RESOLVE_ASSERT(mode == resolveEager || mode == resolveLazy);
203         RESOLVE_ASSERT(result);
204
205 #ifdef RESOLVE_VERBOSE
206         fprintf(stderr,"resolve_classref_or_classinfo(");
207         utf_fprint(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
208         fprintf(stderr,",%i,%i)\n",mode,link);
209 #endif
210
211         *result = NULL;
212
213         if (IS_CLASSREF(cls)) {
214                 /* we must resolve this reference */
215                 if (!resolve_class_from_name(cls.ref->referer,refmethod,cls.ref->name,
216                                                                         mode,link,&c))
217                         return false; /* exception */
218         }
219         else {
220                 /* cls has already been resolved */
221                 c = cls.cls;
222                 RESOLVE_ASSERT(c->loaded);
223         }
224         RESOLVE_ASSERT(c || (mode == resolveLazy));
225
226         if (!c)
227                 return true; /* be lazy */
228         
229         RESOLVE_ASSERT(c);
230         RESOLVE_ASSERT(c->loaded);
231
232         if (link) {
233                 if (!c->linked)
234                         if (!link_class(c))
235                                 return false; /* exception */
236                 RESOLVE_ASSERT(c->linked);
237         }
238
239         /* succeeded */
240         *result = c;
241         return true;
242 }
243
244 bool 
245 resolve_class_from_typedesc(typedesc *d, bool link, classinfo **result)
246 {
247         classinfo *cls;
248         
249         RESOLVE_ASSERT(d);
250         RESOLVE_ASSERT(result);
251
252         *result = NULL;
253
254 #ifdef RESOLVE_VERBOSE
255         fprintf(stderr,"resolve_class_from_typedesc(");
256         descriptor_debug_print_typedesc(stderr,d);
257         fprintf(stderr,",%i)\n",link);
258 #endif
259
260         if (d->classref) {
261                 /* a reference type */
262                 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
263                                                                                    resolveEager,link,&cls))
264                         return false; /* exception */
265         }
266         else {
267                 /* a primitive type */
268                 cls = primitivetype_table[d->decltype].class_primitive;
269                 RESOLVE_ASSERT(cls->loaded);
270                 if (!cls->linked)
271                         if (!link_class(cls))
272                                 return false; /* exception */
273         }
274         RESOLVE_ASSERT(cls);
275         RESOLVE_ASSERT(cls->loaded);
276         RESOLVE_ASSERT(!link || cls->linked);
277
278 #ifdef RESOLVE_VERBOSE
279         fprintf(stderr,"    result = ");utf_fprint(stderr,cls->name);fprintf(stderr,"\n");
280 #endif
281
282         *result = cls;
283         return true;
284 }
285
286 /******************************************************************************/
287 /* SUBTYPE SET CHECKS                                                         */
288 /******************************************************************************/
289
290 /* for documentation see resolve.h */
291 bool
292 resolve_and_check_subtype_set(classinfo *referer,methodinfo *refmethod,
293                                                           unresolved_subtype_set *ref,
294                                                           classref_or_classinfo typeref,
295                                                           bool reversed,
296                                                           resolve_mode_t mode,
297                                                           resolve_err_t error,
298                                                           bool *checked)
299 {
300         classref_or_classinfo *setp;
301         classinfo *result;
302         classinfo *type;
303         typeinfo resultti;
304         typeinfo typeti;
305
306         RESOLVE_ASSERT(referer);
307         RESOLVE_ASSERT(ref);
308         RESOLVE_ASSERT(typeref.any);
309         RESOLVE_ASSERT(mode == resolveLazy || mode == resolveEager);
310         RESOLVE_ASSERT(error == resolveLinkageError || error == resolveIllegalAccessError);
311
312 #ifdef RESOLVE_VERBOSE
313         fprintf(stderr,"resolve_and_check_subtype_set\n");
314         unresolved_subtype_set_debug_dump(ref,stderr);
315         if (IS_CLASSREF(typeref)) {
316                 fprintf(stderr,"    ref: ");utf_fprint(stderr,typeref.ref->name);
317         }
318         else {
319                 fprintf(stderr,"    cls: ");utf_fprint(stderr,typeref.cls->name);
320         }
321         fprintf(stderr,"\n");
322 #endif
323
324         setp = ref->subtyperefs;
325
326         /* an empty set of tests always succeeds */
327         if (!setp || !setp->any) {
328                 if (checked)
329                         *checked = true;
330                 return true;
331         }
332
333         if (checked)
334                 *checked = false;
335
336         /* first resolve the type if necessary */
337         if (!resolve_classref_or_classinfo(refmethod,typeref,mode,true,&type))
338                 return false; /* exception */
339         if (!type)
340                 return true; /* be lazy */
341
342         RESOLVE_ASSERT(type);
343         RESOLVE_ASSERT(type->loaded);
344         RESOLVE_ASSERT(type->linked);
345         TYPEINFO_INIT_CLASSINFO(typeti,type);
346
347         for (; setp->any; ++setp) {
348                 /* first resolve the set member if necessary */
349                 if (!resolve_classref_or_classinfo(refmethod,*setp,mode,true,&result))
350                         return false; /* exception */
351                 if (!result)
352                         return true; /* be lazy */
353
354                 RESOLVE_ASSERT(result);
355                 RESOLVE_ASSERT(result->loaded);
356                 RESOLVE_ASSERT(result->linked);
357
358 #ifdef RESOLVE_VERBOSE
359                 fprintf(stderr,"performing subclass test:\n");
360                 fprintf(stderr,"    ");utf_fprint(stderr,result->name);fputc('\n',stderr);
361                 fprintf(stderr,"  must be a %s of\n",(reversed) ? "superclass" : "subclass");
362                 fprintf(stderr,"    ");utf_fprint(stderr,type->name);fputc('\n',stderr);
363 #endif
364
365                 /* now check the subtype relationship */
366                 TYPEINFO_INIT_CLASSINFO(resultti,result);
367                 if (reversed) {
368                         /* we must test against `true` because `MAYBE` is also != 0 */
369                         if (true != typeinfo_is_assignable_to_class(&typeti,CLASSREF_OR_CLASSINFO(result))) {
370 #ifdef RESOLVE_VERBOSE
371                                 fprintf(stderr,"reversed subclass test failed\n");
372 #endif
373                                 goto throw_error;
374                         }
375                 }
376                 else {
377                         /* we must test against `true` because `MAYBE` is also != 0 */
378                         if (true != typeinfo_is_assignable_to_class(&resultti,CLASSREF_OR_CLASSINFO(type))) {
379 #ifdef RESOLVE_VERBOSE
380                                 fprintf(stderr,"subclass test failed\n");
381 #endif
382                                 goto throw_error;
383                         }
384                 }
385         }
386         
387         /* check succeeds */
388         if (checked)
389                 *checked = true;
390         return true;
391
392 throw_error:
393         if (error == resolveIllegalAccessError)
394                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,
395                                 "illegal access to protected member XXX add message");
396         else
397                 *exceptionptr = new_exception_message(string_java_lang_LinkageError,
398                                 "subtype constraint violated XXX add message");
399         return false; /* exception */
400 }
401
402 /******************************************************************************/
403 /* CLASS RESOLUTION                                                           */
404 /******************************************************************************/
405
406 /* for documentation see resolve.h */
407 bool
408 resolve_class(unresolved_class *ref,
409                           resolve_mode_t mode,
410                           classinfo **result)
411 {
412         classinfo *cls;
413         bool checked;
414         
415         RESOLVE_ASSERT(ref);
416         RESOLVE_ASSERT(result);
417         RESOLVE_ASSERT(mode == resolveLazy || mode == resolveEager);
418
419         *result = NULL;
420
421 #ifdef RESOLVE_VERBOSE
422         unresolved_class_debug_dump(ref,stderr);
423 #endif
424
425         /* first we must resolve the class */
426         if (!resolve_classref(ref->referermethod,
427                                               ref->classref,mode,true,&cls))
428         {
429                 /* the class reference could not be resolved */
430                 return false; /* exception */
431         }
432         if (!cls)
433                 return true; /* be lazy */
434
435         RESOLVE_ASSERT(cls);
436         RESOLVE_ASSERT(cls->loaded && cls->linked);
437
438         /* now we check the subtype constraints */
439         if (!resolve_and_check_subtype_set(ref->classref->referer,ref->referermethod,
440                                                                            &(ref->subtypeconstraints),
441                                                                            CLASSREF_OR_CLASSINFO(cls),
442                                                                            false,
443                                                                            mode,
444                                                                            resolveLinkageError,&checked))
445         {
446                 return false; /* exception */
447         }
448         if (!checked)
449                 return true; /* be lazy */
450
451         /* succeed */
452         *result = cls;
453         return true;
454 }
455
456 /******************************************************************************/
457 /* FIELD RESOLUTION                                                           */
458 /******************************************************************************/
459
460 /* for documentation see resolve.h */
461 bool
462 resolve_field(unresolved_field *ref,
463                           resolve_mode_t mode,
464                           fieldinfo **result)
465 {
466         classinfo *referer;
467         classinfo *container;
468         classinfo *declarer;
469         constant_classref *fieldtyperef;
470         fieldinfo *fi;
471         bool checked;
472         
473         RESOLVE_ASSERT(ref);
474         RESOLVE_ASSERT(result);
475         RESOLVE_ASSERT(mode == resolveLazy || mode == resolveEager);
476
477         *result = NULL;
478
479 #ifdef RESOLVE_VERBOSE
480         unresolved_field_debug_dump(ref,stderr);
481 #endif
482
483         /* the class containing the reference */
484         referer = ref->fieldref->classref->referer;
485         RESOLVE_ASSERT(referer);
486
487         /* first we must resolve the class containg the field */
488         if (!resolve_class_from_name(referer,ref->referermethod,
489                                            ref->fieldref->classref->name,mode,true,&container))
490         {
491                 /* the class reference could not be resolved */
492                 return false; /* exception */
493         }
494         if (!container)
495                 return true; /* be lazy */
496
497         RESOLVE_ASSERT(container);
498         RESOLVE_ASSERT(container->loaded && container->linked);
499
500         /* now we must find the declaration of the field in `container`
501          * or one of its superclasses */
502
503 #ifdef RESOLVE_VERBOSE
504                 fprintf(stderr,"    resolving field in class...\n");
505 #endif
506
507         fi = class_resolvefield(container,
508                                                         ref->fieldref->name,ref->fieldref->descriptor,
509                                                         referer,true);
510         if (!fi)
511                 return false; /* exception */
512
513         /* { the field reference has been resolved } */
514         declarer = fi->class;
515         RESOLVE_ASSERT(declarer);
516         RESOLVE_ASSERT(declarer->loaded && declarer->linked);
517
518 #ifdef RESOLVE_VERBOSE
519                 fprintf(stderr,"    checking static...\n");
520 #endif
521
522         /* check static */
523         if (((fi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {
524                 /* a static field is accessed via an instance, or vice versa */
525                 *exceptionptr = new_exception_message(string_java_lang_IncompatibleClassChangeError,
526                                 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
527                                                          : "instance field accessed without instance");
528                 return false; /* exception */
529         }
530
531         /* for non-static accesses we have to check the constraints on the instance type */
532         if ((ref->flags & RESOLVE_STATIC) == 0) {
533 #ifdef RESOLVE_VERBOSE
534                 fprintf(stderr,"    checking instance types...\n");
535 #endif
536
537                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
538                                                                                    &(ref->instancetypes),
539                                                                                    CLASSREF_OR_CLASSINFO(container),
540                                                                                    false,
541                                                                                    mode,
542                                                                                    resolveLinkageError,&checked))
543                 {
544                         return false; /* exception */
545                 }
546                 if (!checked)
547                         return true; /* be lazy */
548         }
549
550         fieldtyperef = ref->fieldref->parseddesc.fd->classref;
551
552         /* for PUT* instructions we have to check the constraints on the value type */
553         if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
554                 RESOLVE_ASSERT(fieldtyperef);
555                 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
556                         /* check subtype constraints */
557                         if (!resolve_and_check_subtype_set(referer,ref->referermethod,
558                                                                                            &(ref->valueconstraints),
559                                                                                            CLASSREF_OR_CLASSINFO(fieldtyperef),
560                                                                                            false,
561                                                                                            mode,
562                                                                                            resolveLinkageError,&checked))
563                         {
564                                 return false; /* exception */
565                         }
566                         if (!checked)
567                                 return true; /* be lazy */
568                 }
569         }
570                                                                            
571         /* check access rights */
572         if (!is_accessible_member(referer,declarer,fi->flags)) {
573                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,
574                                 "field is not accessible XXX add message");
575                 return false; /* exception */
576         }
577
578         /* check protected access */
579         if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
580                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
581                                                                                    &(ref->instancetypes),
582                                                                                    CLASSREF_OR_CLASSINFO(referer),
583                                                                                    false,
584                                                                                    mode,
585                                                                                    resolveIllegalAccessError,&checked))
586                 {
587                         return false; /* exception */
588                 }
589                 if (!checked)
590                         return true; /* be lazy */
591         }
592
593         /* impose loading constraint on field type */
594         if (fi->type == TYPE_ADR) {
595                 RESOLVE_ASSERT(fieldtyperef);
596                 if (!classcache_add_constraint(declarer->classloader,referer->classloader,
597                                                                            fieldtyperef->name))
598                         return false; /* exception */
599         }
600
601         /* succeed */
602         *result = fi;
603         return true;
604 }
605
606 /******************************************************************************/
607 /* METHOD RESOLUTION                                                          */
608 /******************************************************************************/
609
610 /* for documentation see resolve.h */
611 bool
612 resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
613 {
614         classinfo *referer;
615         classinfo *container;
616         classinfo *declarer;
617         methodinfo *mi;
618         typedesc *paramtypes;
619         int instancecount;
620         int i;
621         bool checked;
622         
623         RESOLVE_ASSERT(ref);
624         RESOLVE_ASSERT(result);
625         RESOLVE_ASSERT(mode == resolveLazy || mode == resolveEager);
626
627 #ifdef RESOLVE_VERBOSE
628         unresolved_method_debug_dump(ref,stderr);
629 #endif
630
631         *result = NULL;
632
633         /* the class containing the reference */
634         referer = ref->methodref->classref->referer;
635         RESOLVE_ASSERT(referer);
636
637         /* first we must resolve the class containg the method */
638         if (!resolve_class_from_name(referer,ref->referermethod,
639                                            ref->methodref->classref->name,mode,true,&container))
640         {
641                 /* the class reference could not be resolved */
642                 return false; /* exception */
643         }
644         if (!container)
645                 return true; /* be lazy */
646
647         RESOLVE_ASSERT(container);
648
649         /* now we must find the declaration of the method in `container`
650          * or one of its superclasses */
651
652         if (container->flags & ACC_INTERFACE) {
653                 mi = class_resolveinterfacemethod(container,
654                                                                               ref->methodref->name,
655                                                                                   ref->methodref->descriptor,
656                                                                               referer, true);
657
658         } else {
659                 mi = class_resolveclassmethod(container,
660                                                                           ref->methodref->name,
661                                                                           ref->methodref->descriptor,
662                                                                           referer, true);
663         }
664
665         if (!mi)
666                 return false; /* exception */ /* XXX set exceptionptr? */
667
668         /* { the method reference has been resolved } */
669
670         declarer = mi->class;
671         RESOLVE_ASSERT(declarer);
672
673         /* check static */
674
675         if (((mi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {          /* a static method is accessed via an instance, or vice versa */
676                 *exceptionptr =
677                         new_exception_message(string_java_lang_IncompatibleClassChangeError,
678                                 (mi->flags & ACC_STATIC) ? "static method called via instance"
679                                                          : "instance method called without instance");
680                 return false;
681         }
682
683         /* have the method params already been parsed? no, do it. */
684
685         if (!mi->parseddesc->params)
686                 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
687                         return false;
688                 
689         /* for non-static methods we have to check the constraints on the         */
690         /* instance type                                                          */
691
692         if (!(ref->flags & RESOLVE_STATIC)) {
693                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
694                                                                                    &(ref->instancetypes),
695                                                                                    CLASSREF_OR_CLASSINFO(container),
696                                                                                    false,
697                                                                                    mode,
698                                                                                    resolveLinkageError,&checked))
699                 {
700                         return false; /* exception */
701                 }
702                 if (!checked)
703                         return true; /* be lazy */
704                 instancecount = 1;
705         }
706         else {
707                 instancecount = 0;
708         }
709
710         /* check subtype constraints for TYPE_ADR parameters */
711
712         RESOLVE_ASSERT(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
713         paramtypes = mi->parseddesc->paramtypes;
714         
715         for (i = 0; i < mi->parseddesc->paramcount; i++) {
716                 if (paramtypes[i].type == TYPE_ADR) {
717                         if (ref->paramconstraints) {
718                                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
719                                                         ref->paramconstraints + i,
720                                                         CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
721                                                         false,
722                                                         mode,
723                                                         resolveLinkageError,&checked))
724                                 {
725                                         return false; /* exception */
726                                 }
727                                 if (!checked)
728                                         return true; /* be lazy */
729                         }
730                 }
731         }
732
733         /* check access rights */
734
735         if (!is_accessible_member(referer,declarer,mi->flags)) {
736                 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,
737                                 "method is not accessible XXX add message");
738                 return false; /* exception */
739         }
740
741         /* check protected access */
742
743         if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
744                 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
745                                                                                    &(ref->instancetypes),
746                                                                                    CLASSREF_OR_CLASSINFO(referer),
747                                                                                    false,
748                                                                                    mode,
749                                                                                    resolveIllegalAccessError,&checked))
750                 {
751                         return false; /* exception */
752                 }
753                 if (!checked)
754                         return true; /* be lazy */
755         }
756
757         /* impose loading constraints on parameters (including instance) */
758
759         paramtypes = mi->parseddesc->paramtypes;
760
761         for (i = 0; i < mi->parseddesc->paramcount; i++) {
762                 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
763                         utf *name;
764                         
765                         if (i < instancecount)
766                                 name = container->name; /* XXX should this be declarer->name? */
767                         else
768                                 name = paramtypes[i].classref->name;
769                         
770                         if (!classcache_add_constraint(referer->classloader,
771                                                                                    declarer->classloader, name))
772                                 return false; /* exception */
773                 }
774         }
775
776         /* impose loading constraing onto return type */
777
778         if (ref->methodref->parseddesc.md->returntype.type == TYPE_ADR) {
779                 if (!classcache_add_constraint(referer->classloader,declarer->classloader,
780                                 ref->methodref->parseddesc.md->returntype.classref->name))
781                         return false; /* exception */
782         }
783
784         /* succeed */
785         *result = mi;
786         return true;
787 }
788
789 /******************************************************************************/
790 /* CREATING THE DATA STRUCTURES                                               */
791 /******************************************************************************/
792
793 static bool
794 unresolved_subtype_set_from_typeinfo(classinfo *referer,methodinfo *refmethod,
795                 unresolved_subtype_set *stset,typeinfo *tinfo,
796                 constant_classref *declaredtype)
797 {
798         int count;
799         int i;
800         
801         RESOLVE_ASSERT(stset);
802         RESOLVE_ASSERT(tinfo);
803
804 #ifdef RESOLVE_VERBOSE
805         fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
806 #ifdef TYPEINFO_DEBUG
807         /*typeinfo_print(stderr,tinfo,4);*/
808         fprintf(stderr,"\n");
809 #endif
810         fprintf(stderr,"    declared type:");utf_fprint(stderr,declaredtype->name);
811         fprintf(stderr,"\n");
812 #endif
813
814         if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
815                 *exceptionptr = new_verifyerror(refmethod,
816                                 "Invalid use of returnAddress");
817                 return false;
818         }
819
820         if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
821                 *exceptionptr = new_verifyerror(refmethod,
822                                 "Invalid use of uninitialized object");
823                 return false;
824         }
825
826         /* the nulltype is always assignable (XXX for reversed?) */
827         if (TYPEINFO_IS_NULLTYPE(*tinfo))
828                 goto empty_set;
829
830         /* every type is assignable to (BOOTSTRAP)java.lang.Object */
831         if (declaredtype->name == utf_java_lang_Object
832                         && referer->classloader == NULL)
833         {
834                 goto empty_set;
835         }
836
837         if (tinfo->merged) {
838                 count = tinfo->merged->count;
839                 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
840                 for (i=0; i<count; ++i) {
841                         stset->subtyperefs[i] = tinfo->merged->list[i];
842                 }
843                 stset->subtyperefs[count].any = NULL; /* terminate */
844         }
845         else {
846                 if ((IS_CLASSREF(tinfo->typeclass)
847                                         ? tinfo->typeclass.ref->name 
848                                         : tinfo->typeclass.cls->name) == declaredtype->name)
849                 {
850                         goto empty_set;
851                 }
852                 else {
853                         stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
854                         stset->subtyperefs[0] = tinfo->typeclass;
855                         stset->subtyperefs[1].any = NULL; /* terminate */
856                 }
857         }
858
859         return true;
860
861 empty_set:
862         UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
863         return true;
864 }
865
866 /* create_unresolved_class *****************************************************
867  
868    Create an unresolved_class struct for the given class reference
869   
870    IN:
871            refmethod........the method triggering the resolution (if any)
872            classref.........the class reference
873            valuetype........value type to check against the resolved class
874                                                 may be NULL, if no typeinfo is available
875
876    RETURN VALUE:
877        a pointer to a new unresolved_class struct, or
878            NULL if an exception has been thrown
879
880 *******************************************************************************/
881
882 unresolved_class *
883 create_unresolved_class(methodinfo *refmethod,
884                                                 constant_classref *classref,
885                                                 typeinfo *valuetype)
886 {
887         unresolved_class *ref;
888         
889         RESOLVE_ASSERT(ref);
890         
891 #ifdef RESOLVE_VERBOSE
892         fprintf(stderr,"create_unresolved_class\n");
893         fprintf(stderr,"    referer: ");utf_fprint(stderr,classref->referer->name);fputc('\n',stderr);
894         if (refmethod) {
895                 fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
896                 fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
897         }
898         fprintf(stderr,"    name   : ");utf_fprint(stderr,classref->name);fputc('\n',stderr);
899 #endif
900
901         ref = NEW(unresolved_class);
902         ref->classref = classref;
903         ref->referermethod = refmethod;
904
905         if (valuetype) {
906                 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
907                                         &(ref->subtypeconstraints),valuetype,classref))
908                         return NULL;
909         }
910         else {
911                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
912         }
913
914         return ref;
915 }
916
917 /* create_unresolved_field *****************************************************
918  
919    Create an unresolved_field struct for the given field access instruction
920   
921    IN:
922        referer..........the class containing the reference
923            refmethod........the method triggering the resolution (if any)
924            iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
925
926    RETURN VALUE:
927        a pointer to a new unresolved_field struct, or
928            NULL if an exception has been thrown
929
930 *******************************************************************************/
931
932 unresolved_field *
933 create_unresolved_field(classinfo *referer, methodinfo *refmethod,
934                                                 instruction *iptr)
935 {
936         unresolved_field *ref;
937         constant_FMIref *fieldref = NULL;
938
939 #ifdef RESOLVE_VERBOSE
940         fprintf(stderr,"create_unresolved_field\n");
941         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
942         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
943         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
944 #endif
945
946         ref = NEW(unresolved_field);
947         ref->flags = 0;
948         ref->referermethod = refmethod;
949         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
950
951         switch (iptr[0].opc) {
952                 case ICMD_PUTFIELD:
953                         ref->flags |= RESOLVE_PUTFIELD;
954                         fieldref = (constant_FMIref *) iptr[0].val.a;
955                         break;
956
957                 case ICMD_PUTFIELDCONST:
958                         ref->flags |= RESOLVE_PUTFIELD;
959                         fieldref = (constant_FMIref *) iptr[1].val.a;
960                         break;
961
962                 case ICMD_PUTSTATIC:
963                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
964                         fieldref = (constant_FMIref *) iptr[0].val.a;
965                         break;
966
967                 case ICMD_PUTSTATICCONST:
968                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
969                         fieldref = (constant_FMIref *) iptr[1].val.a;
970                         break;
971
972                 case ICMD_GETFIELD:
973                         fieldref = (constant_FMIref *) iptr[0].val.a;
974                         break;
975                         
976                 case ICMD_GETSTATIC:
977                         ref->flags |= RESOLVE_STATIC;
978                         fieldref = (constant_FMIref *) iptr[0].val.a;
979                         break;
980         }
981         
982         RESOLVE_ASSERT(fieldref);
983
984 #ifdef RESOLVE_VERBOSE
985         fprintf(stderr,"    class  : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
986         fprintf(stderr,"    name   : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
987         fprintf(stderr,"    desc   : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
988         fprintf(stderr,"    type   : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
989         fputc('\n',stderr);
990         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
991 #endif
992
993         ref->fieldref = fieldref;
994
995         return ref;
996 }
997
998 /* constrain_unresolved_field **************************************************
999  
1000    Record subtype constraints for a field access.
1001   
1002    IN:
1003        ref..............the unresolved_field structure of the access
1004        referer..........the class containing the reference
1005            refmethod........the method triggering the resolution (if any)
1006            iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
1007            stack............the input stack of the instruction
1008
1009    RETURN VALUE:
1010        true.............everything ok
1011            false............an exception has been thrown
1012
1013 *******************************************************************************/
1014
1015 bool
1016 constrain_unresolved_field(unresolved_field *ref,
1017                                                    classinfo *referer, methodinfo *refmethod,
1018                                                    instruction *iptr,
1019                                                    stackelement *stack)
1020 {
1021         unresolved_field *ref;
1022         constant_FMIref *fieldref;
1023         stackelement *instanceslot = NULL;
1024         int type;
1025         typeinfo tinfo;
1026         typeinfo *tip = NULL;
1027         typedesc *fd;
1028
1029         RESOLVE_ASSERT(ref);
1030         RESOLVE_ASSERT(stack);
1031
1032         fieldref = ref->fieldref;
1033         RESOLVE_ASSERT(fieldref);
1034
1035 #ifdef RESOLVE_VERBOSE
1036         fprintf(stderr,"constrain_unresolved_field\n");
1037         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1038         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1039         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1040 #endif
1041
1042         switch (iptr[0].opc) {
1043                 case ICMD_PUTFIELD:
1044                         instanceslot = stack->prev;
1045                         tip = &(stack->typeinfo);
1046                         break;
1047
1048                 case ICMD_PUTFIELDCONST:
1049                         instanceslot = stack;
1050                         break;
1051
1052                 case ICMD_PUTSTATIC:
1053                         tip = &(stack->typeinfo);
1054                         break;
1055
1056                 case ICMD_GETFIELD:
1057                         instanceslot = stack;
1058                         break;
1059         }
1060         
1061         RESOLVE_ASSERT(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
1062         fd = fieldref->parseddesc.fd;
1063         RESOLVE_ASSERT(fd);
1064
1065 #ifdef RESOLVE_VERBOSE
1066         fprintf(stderr,"    class  : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
1067         fprintf(stderr,"    name   : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
1068         fprintf(stderr,"    desc   : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
1069         fprintf(stderr,"    type   : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
1070         fputc('\n',stderr);
1071         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1072 #endif
1073
1074         /* record subtype constraints for the instance type, if any */
1075         if (instanceslot) {
1076                 typeinfo *insttip;
1077                 RESOLVE_ASSERT(instanceslot->type == TYPE_ADR);
1078                 
1079                 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && 
1080                                 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1081                 {   /* XXX clean up */
1082                         instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1083                         classinfo *initclass = (ins) ? (classinfo*)ins[-1].val.a 
1084                                                                                  : refmethod->class; /* XXX classrefs */
1085                         RESOLVE_ASSERT(initclass->loaded && initclass->linked);
1086                         TYPEINFO_INIT_CLASSINFO(tinfo,initclass);
1087                         insttip = &tinfo;
1088                 }
1089                 else {
1090                         insttip = &(instanceslot->typeinfo);
1091                 }
1092                 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1093                                         &(ref->instancetypes),insttip,fieldref->classref))
1094                         return false;
1095         }
1096         else {
1097                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1098         }
1099         
1100         /* record subtype constraints for the value type, if any */
1101         type = fd->type;
1102         if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
1103                 if (!tip) {
1104                         /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
1105                         tip = &tinfo;
1106                         if (INSTRUCTION_PUTCONST_VALUE_ADR(iptr)) {
1107                                 RESOLVE_ASSERT(class_java_lang_String);
1108                                 RESOLVE_ASSERT(class_java_lang_String->loaded);
1109                                 RESOLVE_ASSERT(class_java_lang_String->linked);
1110                                 TYPEINFO_INIT_CLASSINFO(tinfo,class_java_lang_String);
1111                         }
1112                         else
1113                                 TYPEINFO_INIT_NULLTYPE(tinfo);
1114                 }
1115                 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1116                                         &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref))
1117                         return false;
1118         }
1119         else {
1120                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
1121         }
1122
1123         return true;
1124 }
1125
1126 /* create_unresolved_method ****************************************************
1127  
1128    Create an unresolved_method struct for the given method invocation
1129   
1130    IN:
1131        referer..........the class containing the reference
1132            refmethod........the method triggering the resolution (if any)
1133            iptr.............the INVOKE* instruction
1134
1135    RETURN VALUE:
1136        a pointer to a new unresolved_method struct, or
1137            NULL if an exception has been thrown
1138
1139 *******************************************************************************/
1140
1141 unresolved_method *
1142 create_unresolved_method(classinfo *referer, methodinfo *refmethod,
1143                                                  instruction *iptr)
1144 {
1145         unresolved_method *ref;
1146         constant_FMIref *methodref;
1147
1148         methodref = (constant_FMIref *) iptr[0].val.a;
1149         RESOLVE_ASSERT(methodref);
1150
1151 #ifdef RESOLVE_VERBOSE
1152         fprintf(stderr,"create_unresolved_method\n");
1153         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1154         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1155         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1156         fprintf(stderr,"    class  : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1157         fprintf(stderr,"    name   : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1158         fprintf(stderr,"    desc   : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1159         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1160 #endif
1161
1162         ref = NEW(unresolved_method);
1163         ref->flags = 0;
1164         ref->referermethod = refmethod;
1165         ref->methodref = methodref;
1166         ref->paramconstraints = NULL;
1167         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1168
1169         switch (iptr[0].opc) {
1170                 case ICMD_INVOKESTATIC:
1171                         ref->flags |= RESOLVE_STATIC;
1172                         break;
1173                 case ICMD_INVOKEVIRTUAL:
1174                 case ICMD_INVOKESPECIAL:
1175                 case ICMD_INVOKEINTERFACE:
1176                         break;
1177                 default:
1178                         RESOLVE_ASSERT(false);
1179         }
1180
1181         return ref;
1182 }
1183
1184 /* constrain_unresolved_method *************************************************
1185  
1186    Record subtype constraints for the arguments of a method call.
1187   
1188    IN:
1189        ref..............the unresolved_method structure of the call
1190        referer..........the class containing the reference
1191            refmethod........the method triggering the resolution (if any)
1192            iptr.............the INVOKE* instruction
1193            stack............the input stack of the instruction
1194
1195    RETURN VALUE:
1196        true.............everything ok
1197            false............an exception has been thrown
1198
1199 *******************************************************************************/
1200
1201 bool
1202 constrain_unresolved_method(unresolved_method *ref,
1203                                                         classinfo *referer, methodinfo *refmethod,
1204                                                         instruction *iptr,
1205                                                         stackelement *stack)
1206 {
1207         constant_FMIref *methodref;
1208         stackelement *instanceslot = NULL;
1209         stackelement *param;
1210         methoddesc *md;
1211         typeinfo tinfo;
1212         int i,j;
1213         int type;
1214
1215         RESOLVE_ASSERT(ref);
1216         RESOLVE_ASSERT(stack);
1217         methodref = ref->methodref;
1218         RESOLVE_ASSERT(methodref);
1219         md = methodref->parseddesc.md;
1220         RESOLVE_ASSERT(md);
1221
1222 #ifdef RESOLVE_VERBOSE
1223         fprintf(stderr,"constrain_unresolved_method\n");
1224         fprintf(stderr,"    referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1225         fprintf(stderr,"    rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1226         fprintf(stderr,"    rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1227         fprintf(stderr,"    class  : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1228         fprintf(stderr,"    name   : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1229         fprintf(stderr,"    desc   : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1230         /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1231 #endif
1232
1233         if ((ref->flags & RESOLVE_STATIC) == 0) {
1234                 /* find the instance slot under all the parameter slots on the stack */
1235                 instanceslot = stack;
1236                 for (i=0; i<md->paramcount; ++i)
1237                         instanceslot = instanceslot->prev;
1238         }
1239         
1240         RESOLVE_ASSERT(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
1241
1242         /* record subtype constraints for the instance type, if any */
1243         if (instanceslot) {
1244                 typeinfo *tip;
1245                 
1246                 RESOLVE_ASSERT(instanceslot->type == TYPE_ADR);
1247                 
1248                 if (iptr[0].opc == ICMD_INVOKESPECIAL && 
1249                                 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1250                 {   /* XXX clean up */
1251                         instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1252                         classinfo *initclass = (ins) ? (classinfo*)ins[-1].val.a 
1253                                                                                  : refmethod->class; /* XXX classrefs */
1254                         RESOLVE_ASSERT(initclass->loaded && initclass->linked);
1255                         TYPEINFO_INIT_CLASSINFO(tinfo,initclass);
1256                         tip = &tinfo;
1257                 }
1258                 else {
1259                         tip = &(instanceslot->typeinfo);
1260                 }
1261                 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1262                                         &(ref->instancetypes),tip,methodref->classref))
1263                         return false;
1264         }
1265         
1266         /* record subtype constraints for the parameter types, if any */
1267         param = stack;
1268         for (i=md->paramcount-1; i>=0; --i, param=param->prev) {
1269                 type = md->paramtypes[i].type;
1270
1271                 RESOLVE_ASSERT(param);
1272                 RESOLVE_ASSERT(type == param->type);
1273
1274                 if (type == TYPE_ADR) {
1275                         if (!ref->paramconstraints) {
1276                                 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
1277                                 for (j=md->paramcount-1; j>i; --j)
1278                                         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
1279                         }
1280                         RESOLVE_ASSERT(ref->paramconstraints);
1281                         if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1282                                                 ref->paramconstraints + i,&(param->typeinfo),
1283                                                 md->paramtypes[i].classref))
1284                                 return false;
1285                 }
1286                 else {
1287                         if (ref->paramconstraints)
1288                                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
1289                 }
1290         }
1291
1292         return true;
1293 }
1294
1295 /******************************************************************************/
1296 /* FREEING MEMORY                                                             */
1297 /******************************************************************************/
1298
1299 inline static void 
1300 unresolved_subtype_set_free_list(classref_or_classinfo *list)
1301 {
1302         if (list) {
1303                 classref_or_classinfo *p = list;
1304
1305                 /* this is silly. we *only* need to count the elements for MFREE */
1306                 while ((p++)->any)
1307                         ;
1308                 MFREE(list,classref_or_classinfo,(p - list));
1309         }
1310 }
1311
1312 /* unresolved_class_free *******************************************************
1313  
1314    Free the memory used by an unresolved_class
1315   
1316    IN:
1317        ref..............the unresolved_class
1318
1319 *******************************************************************************/
1320
1321 void 
1322 unresolved_class_free(unresolved_class *ref)
1323 {
1324         RESOLVE_ASSERT(ref);
1325
1326         unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
1327         FREE(ref,unresolved_class);
1328 }
1329
1330 /* unresolved_field_free *******************************************************
1331  
1332    Free the memory used by an unresolved_field
1333   
1334    IN:
1335        ref..............the unresolved_field
1336
1337 *******************************************************************************/
1338
1339 void 
1340 unresolved_field_free(unresolved_field *ref)
1341 {
1342         RESOLVE_ASSERT(ref);
1343
1344         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1345         unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
1346         FREE(ref,unresolved_field);
1347 }
1348
1349 /* unresolved_method_free ******************************************************
1350  
1351    Free the memory used by an unresolved_method
1352   
1353    IN:
1354        ref..............the unresolved_method
1355
1356 *******************************************************************************/
1357
1358 void 
1359 unresolved_method_free(unresolved_method *ref)
1360 {
1361         RESOLVE_ASSERT(ref);
1362
1363         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1364         if (ref->paramconstraints) {
1365                 int i;
1366                 int count = ref->methodref->parseddesc.md->paramcount;
1367
1368                 for (i=0; i<count; ++i)
1369                         unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
1370                 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
1371         }
1372         FREE(ref,unresolved_method);
1373 }
1374
1375 /******************************************************************************/
1376 /* DEBUG DUMPS                                                                */
1377 /******************************************************************************/
1378
1379 /* unresolved_subtype_set_debug_dump *******************************************
1380  
1381    Print debug info for unresolved_subtype_set to stream
1382   
1383    IN:
1384        stset............the unresolved_subtype_set
1385            file.............the stream
1386
1387 *******************************************************************************/
1388
1389 void
1390 unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
1391 {
1392         classref_or_classinfo *p;
1393         
1394         if (SUBTYPESET_IS_EMPTY(*stset)) {
1395                 fprintf(file,"        (empty)\n");
1396         }
1397         else {
1398                 p = stset->subtyperefs;
1399                 for (;p->any; ++p) {
1400                         if (IS_CLASSREF(*p)) {
1401                                 fprintf(file,"        ref: ");
1402                                 utf_fprint(file,p->ref->name);
1403                         }
1404                         else {
1405                                 fprintf(file,"        cls: ");
1406                                 utf_fprint(file,p->cls->name);
1407                         }
1408                         fputc('\n',file);
1409                 }
1410         }
1411 }
1412
1413 /* unresolved_class_debug_dump *************************************************
1414  
1415    Print debug info for unresolved_class to stream
1416   
1417    IN:
1418        ref..............the unresolved_class
1419            file.............the stream
1420
1421 *******************************************************************************/
1422
1423 void 
1424 unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
1425 {
1426         fprintf(file,"unresolved_class(%p):\n",(void *)ref);
1427         if (ref) {
1428                 fprintf(file,"    referer   : ");
1429                 utf_fprint(file,ref->classref->referer->name); fputc('\n',file);
1430                 fprintf(file,"    refmethod  : ");
1431                 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
1432                 fprintf(file,"    refmethodd : ");
1433                 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
1434                 fprintf(file,"    classname : ");
1435                 utf_fprint(file,ref->classref->name); fputc('\n',file);
1436                 fprintf(file,"    subtypeconstraints:\n");
1437                 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
1438         }
1439 }
1440
1441 /* unresolved_field_debug_dump *************************************************
1442  
1443    Print debug info for unresolved_field to stream
1444   
1445    IN:
1446        ref..............the unresolved_field
1447            file.............the stream
1448
1449 *******************************************************************************/
1450
1451 void 
1452 unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
1453 {
1454         fprintf(file,"unresolved_field(%p):\n",(void *)ref);
1455         if (ref) {
1456                 fprintf(file,"    referer   : ");
1457                 utf_fprint(file,ref->fieldref->classref->referer->name); fputc('\n',file);
1458                 fprintf(file,"    refmethod  : ");
1459                 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
1460                 fprintf(file,"    refmethodd : ");
1461                 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
1462                 fprintf(file,"    classname : ");
1463                 utf_fprint(file,ref->fieldref->classref->name); fputc('\n',file);
1464                 fprintf(file,"    name      : ");
1465                 utf_fprint(file,ref->fieldref->name); fputc('\n',file);
1466                 fprintf(file,"    descriptor: ");
1467                 utf_fprint(file,ref->fieldref->descriptor); fputc('\n',file);
1468                 fprintf(file,"    parseddesc: ");
1469                 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
1470                 fprintf(file,"    flags     : %04x\n",ref->flags);
1471                 fprintf(file,"    instancetypes:\n");
1472                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
1473                 fprintf(file,"    valueconstraints:\n");
1474                 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
1475         }
1476 }
1477
1478 /* unresolved_method_debug_dump ************************************************
1479  
1480    Print debug info for unresolved_method to stream
1481   
1482    IN:
1483        ref..............the unresolved_method
1484            file.............the stream
1485
1486 *******************************************************************************/
1487
1488 void 
1489 unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
1490 {
1491         int i;
1492
1493         fprintf(file,"unresolved_method(%p):\n",(void *)ref);
1494         if (ref) {
1495                 fprintf(file,"    referer   : ");
1496                 utf_fprint(file,ref->methodref->classref->referer->name); fputc('\n',file);
1497                 fprintf(file,"    refmethod  : ");
1498                 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
1499                 fprintf(file,"    refmethodd : ");
1500                 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
1501                 fprintf(file,"    classname : ");
1502                 utf_fprint(file,ref->methodref->classref->name); fputc('\n',file);
1503                 fprintf(file,"    name      : ");
1504                 utf_fprint(file,ref->methodref->name); fputc('\n',file);
1505                 fprintf(file,"    descriptor: ");
1506                 utf_fprint(file,ref->methodref->descriptor); fputc('\n',file);
1507                 fprintf(file,"    parseddesc: ");
1508                 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
1509                 fprintf(file,"    flags     : %04x\n",ref->flags);
1510                 fprintf(file,"    instancetypes:\n");
1511                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
1512                 fprintf(file,"    paramconstraints:\n");
1513                 if (ref->paramconstraints) {
1514                         for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
1515                                 fprintf(file,"      param %d:\n",i);
1516                                 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
1517                         }
1518                 } 
1519                 else {
1520                         fprintf(file,"      (empty)\n");
1521                 }
1522         }
1523 }
1524
1525 /*
1526  * These are local overrides for various environment variables in Emacs.
1527  * Please do not remove this and leave it at the end of the file, where
1528  * Emacs will automagically detect them.
1529  * ---------------------------------------------------------------------
1530  * Local variables:
1531  * mode: c
1532  * indent-tabs-mode: t
1533  * c-basic-offset: 4
1534  * tab-width: 4
1535  * End:
1536  * vim:noexpandtab:sw=4:ts=4:
1537  */
1538