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