PR163: descriptor_params_from_paramtypes is protected by a mutex now (per descriptor...
[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         descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
2071
2072         /* cache the result of the resolution */
2073
2074         methodref->p.method = mi;
2075
2076         /* succeed */
2077
2078         return resolveSucceeded;
2079 }
2080
2081 /* resolve_method **************************************************************
2082  
2083    Resolve an unresolved method reference
2084   
2085    IN:
2086        ref..............struct containing the reference
2087        mode.............mode of resolution:
2088                             resolveLazy...only resolve if it does not
2089                                           require loading classes
2090                             resolveEager..load classes if necessary
2091   
2092    OUT:
2093        *result..........set to the result of resolution, or to NULL if
2094                         the reference has not been resolved
2095                         In the case of an exception, *result is
2096                         guaranteed to be set to NULL.
2097   
2098    RETURN VALUE:
2099        true.............everything ok 
2100                         (*result may still be NULL for resolveLazy)
2101        false............an exception has been thrown
2102    
2103 *******************************************************************************/
2104
2105 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2106 {
2107         classinfo *referer;
2108         classinfo *container;
2109         classinfo *declarer;
2110         methodinfo *mi;
2111         typedesc *paramtypes;
2112         int instancecount;
2113         int i;
2114         resolve_result_t checkresult;
2115
2116         assert(ref);
2117         assert(result);
2118         assert(mode == resolveLazy || mode == resolveEager);
2119
2120 #ifdef RESOLVE_VERBOSE
2121         unresolved_method_debug_dump(ref,stdout);
2122 #endif
2123
2124         *result = NULL;
2125
2126         /* the class containing the reference */
2127
2128         referer = ref->referermethod->clazz;
2129         assert(referer);
2130
2131         /* check if the method itself is already resolved */
2132
2133         if (IS_FMIREF_RESOLVED(ref->methodref)) {
2134                 mi = ref->methodref->p.method;
2135                 container = mi->clazz;
2136                 goto resolved_the_method;
2137         }
2138
2139         /* first we must resolve the class containing the method */
2140
2141         if (!resolve_class_from_name(referer,ref->referermethod,
2142                                            ref->methodref->p.classref->name,mode,true,true,&container))
2143         {
2144                 /* the class reference could not be resolved */
2145                 return false; /* exception */
2146         }
2147         if (!container)
2148                 return true; /* be lazy */
2149
2150         assert(container);
2151         assert(container->state & CLASS_LINKED);
2152
2153         /* now we must find the declaration of the method in `container`
2154          * or one of its superclasses */
2155
2156         if (container->flags & ACC_INTERFACE) {
2157                 mi = class_resolveinterfacemethod(container,
2158                                                                               ref->methodref->name,
2159                                                                                   ref->methodref->descriptor,
2160                                                                               referer, true);
2161
2162         } else {
2163                 mi = class_resolveclassmethod(container,
2164                                                                           ref->methodref->name,
2165                                                                           ref->methodref->descriptor,
2166                                                                           referer, true);
2167         }
2168
2169         if (!mi) {
2170                 if (mode == resolveLazy) {
2171                         /* The method does not exist. But since we were called lazily, */
2172                         /* this error must not be reported now. (It will be reported   */
2173                         /* if eager resolving of this method is ever tried.)           */
2174
2175                         exceptions_clear_exception();
2176                         return true; /* be lazy */
2177                 }
2178
2179                 return false; /* exception */ /* XXX set exceptionptr? */
2180         }
2181
2182         /* { the method reference has been resolved } */
2183
2184         if (ref->flags & RESOLVE_SPECIAL) {
2185                 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2186                 if (!mi)
2187                         return false; /* exception */
2188         }
2189
2190         /* have the method params already been parsed? no, do it. */
2191
2192         descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
2193
2194         /* cache the resolution */
2195
2196         ref->methodref->p.method = mi;
2197
2198 resolved_the_method:
2199
2200 #ifdef ENABLE_VERIFIER
2201         if (opt_verify) {
2202
2203                 checkresult = resolve_method_verifier_checks(
2204                                 ref->referermethod,
2205                                 ref->methodref,
2206                                 mi,
2207                                 (ref->flags & RESOLVE_STATIC));
2208
2209                 if (checkresult != resolveSucceeded)
2210                         return (bool) checkresult;
2211
2212                 /* impose loading constraints on params and return type */
2213
2214                 if (!resolve_method_loading_constraints(referer, mi))
2215                         return false;
2216
2217                 declarer = mi->clazz;
2218                 assert(declarer);
2219                 assert(referer->state & CLASS_LINKED);
2220
2221                 /* for non-static methods we have to check the constraints on the         */
2222                 /* instance type                                                          */
2223
2224                 if (!(ref->flags & RESOLVE_STATIC)) {
2225                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
2226                                         &(ref->instancetypes),
2227                                         CLASSREF_OR_CLASSINFO(container),
2228                                         mode,
2229                                         resolveLinkageError);
2230                         if (checkresult != resolveSucceeded)
2231                                 return (bool) checkresult;
2232                         instancecount = 1;
2233                 }
2234                 else {
2235                         instancecount = 0;
2236                 }
2237
2238                 /* check subtype constraints for TYPE_ADR parameters */
2239
2240                 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2241                 paramtypes = mi->parseddesc->paramtypes;
2242
2243                 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2244                         if (paramtypes[i+instancecount].type == TYPE_ADR) {
2245                                 if (ref->paramconstraints) {
2246                                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
2247                                                         ref->paramconstraints + i,
2248                                                         CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2249                                                         mode,
2250                                                         resolveLinkageError);
2251                                         if (checkresult != resolveSucceeded)
2252                                                 return (bool) checkresult;
2253                                 }
2254                         }
2255                 }
2256
2257                 /* check protected access */
2258
2259                 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2260                 {
2261                         checkresult = resolve_and_check_subtype_set(ref->referermethod,
2262                                         &(ref->instancetypes),
2263                                         CLASSREF_OR_CLASSINFO(referer),
2264                                         mode,
2265                                         resolveIllegalAccessError);
2266                         if (checkresult != resolveSucceeded)
2267                                 return (bool) checkresult;
2268                 }
2269         }
2270 #endif /* ENABLE_VERIFIER */
2271
2272         /* succeed */
2273         *result = mi;
2274         return true;
2275 }
2276
2277 /* resolve_method_eager ********************************************************
2278  
2279    Resolve an unresolved method reference eagerly.
2280   
2281    IN:
2282        ref..............struct containing the reference
2283    
2284    RETURN VALUE:
2285        methodinfo * to the method, or
2286            NULL if an exception has been thrown
2287    
2288 *******************************************************************************/
2289
2290 methodinfo * resolve_method_eager(unresolved_method *ref)
2291 {
2292         methodinfo *mi;
2293
2294         if (!resolve_method(ref,resolveEager,&mi))
2295                 return NULL;
2296
2297         return mi;
2298 }
2299
2300 /******************************************************************************/
2301 /* CREATING THE DATA STRUCTURES                                               */
2302 /******************************************************************************/
2303
2304 #ifdef ENABLE_VERIFIER
2305 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2306                                                                                                  methodinfo *refmethod,
2307                                                                                                  unresolved_subtype_set *stset,
2308                                                                                                  typeinfo_t *tinfo,
2309                                                                                                  utf *declaredclassname)
2310 {
2311         int count;
2312         int i;
2313
2314         assert(stset);
2315         assert(tinfo);
2316
2317 #ifdef RESOLVE_VERBOSE
2318         printf("unresolved_subtype_set_from_typeinfo\n");
2319 #ifdef TYPEINFO_DEBUG
2320         typeinfo_print(stdout,tinfo,4);
2321 #endif
2322         printf("    declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2323         printf("\n");
2324 #endif
2325
2326         if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2327                 exceptions_throw_verifyerror(refmethod,
2328                                 "Invalid use of returnAddress");
2329                 return false;
2330         }
2331
2332         if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2333                 exceptions_throw_verifyerror(refmethod,
2334                                 "Invalid use of uninitialized object");
2335                 return false;
2336         }
2337
2338         /* the nulltype is always assignable */
2339         if (TYPEINFO_IS_NULLTYPE(*tinfo))
2340                 goto empty_set;
2341
2342         /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2343         if (declaredclassname == utf_java_lang_Object
2344                         && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2345         {
2346                 goto empty_set;
2347         }
2348
2349         if (tinfo->merged) {
2350                 count = tinfo->merged->count;
2351                 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2352                 for (i=0; i<count; ++i) {
2353                         classref_or_classinfo c = tinfo->merged->list[i];
2354                         if (tinfo->dimension > 0) {
2355                                 /* a merge of array types */
2356                                 /* the merged list contains the possible _element_ types, */
2357                                 /* so we have to create array types with these elements.  */
2358                                 if (IS_CLASSREF(c)) {
2359                                         c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2360                                 }
2361                                 else {
2362                                         c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2363                                 }
2364                         }
2365                         stset->subtyperefs[i] = c;
2366                 }
2367                 stset->subtyperefs[count].any = NULL; /* terminate */
2368         }
2369         else {
2370                 if ((IS_CLASSREF(tinfo->typeclass)
2371                                         ? tinfo->typeclass.ref->name
2372                                         : tinfo->typeclass.cls->name) == declaredclassname)
2373                 {
2374                         /* the class names are the same */
2375                     /* equality is guaranteed by the loading constraints */
2376                         goto empty_set;
2377                 }
2378                 else {
2379                         stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2380                         stset->subtyperefs[0] = tinfo->typeclass;
2381                         stset->subtyperefs[1].any = NULL; /* terminate */
2382                 }
2383         }
2384
2385         return true;
2386
2387 empty_set:
2388         UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2389         return true;
2390 }
2391 #endif /* ENABLE_VERIFIER */
2392
2393 /* create_unresolved_class *****************************************************
2394  
2395    Create an unresolved_class struct for the given class reference
2396   
2397    IN:
2398            refmethod........the method triggering the resolution (if any)
2399            classref.........the class reference
2400            valuetype........value type to check against the resolved class
2401                                                 may be NULL, if no typeinfo is available
2402
2403    RETURN VALUE:
2404        a pointer to a new unresolved_class struct, or
2405            NULL if an exception has been thrown
2406
2407 *******************************************************************************/
2408
2409 #ifdef ENABLE_VERIFIER
2410 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2411                                                                                    constant_classref *classref,
2412                                                                                    typeinfo_t *valuetype)
2413 {
2414         unresolved_class *ref;
2415
2416 #ifdef RESOLVE_VERBOSE
2417         printf("create_unresolved_class\n");
2418         printf("    referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2419         if (refmethod) {
2420                 printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2421                 printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2422         }
2423         printf("    name   : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2424 #endif
2425
2426         ref = NEW(unresolved_class);
2427         ref->classref = classref;
2428         ref->referermethod = refmethod;
2429
2430         if (valuetype) {
2431                 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2432                                         &(ref->subtypeconstraints),valuetype,classref->name))
2433                         return NULL;
2434         }
2435         else {
2436                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2437         }
2438
2439         return ref;
2440 }
2441 #endif /* ENABLE_VERIFIER */
2442
2443 /* resolve_create_unresolved_field *********************************************
2444  
2445    Create an unresolved_field struct for the given field access instruction
2446   
2447    IN:
2448        referer..........the class containing the reference
2449            refmethod........the method triggering the resolution (if any)
2450            iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2451
2452    RETURN VALUE:
2453        a pointer to a new unresolved_field struct, or
2454            NULL if an exception has been thrown
2455
2456 *******************************************************************************/
2457
2458 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2459                                                                                                    methodinfo *refmethod,
2460                                                                                                    instruction *iptr)
2461 {
2462         unresolved_field *ref;
2463         constant_FMIref *fieldref = NULL;
2464
2465 #ifdef RESOLVE_VERBOSE
2466         printf("create_unresolved_field\n");
2467         printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2468         printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2469         printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2470 #endif
2471
2472         ref = NEW(unresolved_field);
2473         ref->flags = 0;
2474         ref->referermethod = refmethod;
2475         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2476
2477         switch (iptr->opc) {
2478                 case ICMD_PUTFIELD:
2479                         ref->flags |= RESOLVE_PUTFIELD;
2480                         break;
2481
2482                 case ICMD_PUTFIELDCONST:
2483                         ref->flags |= RESOLVE_PUTFIELD;
2484                         break;
2485
2486                 case ICMD_PUTSTATIC:
2487                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2488                         break;
2489
2490                 case ICMD_PUTSTATICCONST:
2491                         ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2492                         break;
2493
2494                 case ICMD_GETFIELD:
2495                         break;
2496
2497                 case ICMD_GETSTATIC:
2498                         ref->flags |= RESOLVE_STATIC;
2499                         break;
2500
2501 #if !defined(NDEBUG)
2502                 default:
2503                         assert(false);
2504 #endif
2505         }
2506
2507         fieldref = iptr->sx.s23.s3.fmiref;
2508
2509         assert(fieldref);
2510
2511 #ifdef RESOLVE_VERBOSE
2512 /*      printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2513         printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2514         printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2515         printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2516         fputc('\n',stdout);
2517 #endif
2518
2519         ref->fieldref = fieldref;
2520
2521         return ref;
2522 }
2523
2524 /* resolve_constrain_unresolved_field ******************************************
2525  
2526    Record subtype constraints for a field access.
2527   
2528    IN:
2529        ref..............the unresolved_field structure of the access
2530        referer..........the class containing the reference
2531            refmethod........the method triggering the resolution (if any)
2532            instanceti.......instance typeinfo, if available
2533            valueti..........value typeinfo, if available
2534
2535    RETURN VALUE:
2536        true.............everything ok
2537            false............an exception has been thrown
2538
2539 *******************************************************************************/
2540
2541 #if defined(ENABLE_VERIFIER)
2542 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2543                                                                                 classinfo *referer, 
2544                                                                                 methodinfo *refmethod,
2545                                                                             typeinfo_t *instanceti,
2546                                                                             typeinfo_t *valueti)
2547 {
2548         constant_FMIref *fieldref;
2549         int type;
2550         typeinfo_t tinfo;
2551         typedesc *fd;
2552
2553         assert(ref);
2554
2555         fieldref = ref->fieldref;
2556         assert(fieldref);
2557
2558 #ifdef RESOLVE_VERBOSE
2559         printf("constrain_unresolved_field\n");
2560         printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2561         printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2562         printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2563 /*      printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2564         printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2565         printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2566         printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2567         fputc('\n',stdout);
2568 #endif
2569
2570         assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2571         fd = fieldref->parseddesc.fd;
2572         assert(fd);
2573
2574         /* record subtype constraints for the instance type, if any */
2575         if (instanceti) {
2576                 typeinfo_t *insttip;
2577
2578                 /* The instanceslot must contain a reference to a non-array type */
2579                 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2580                         exceptions_throw_verifyerror(refmethod, 
2581                                         "illegal instruction: field access on non-reference");
2582                         return false;
2583                 }
2584                 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2585                         exceptions_throw_verifyerror(refmethod, 
2586                                         "illegal instruction: field access on array");
2587                         return false;
2588                 }
2589
2590                 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2591                                 TYPEINFO_IS_NEWOBJECT(*instanceti))
2592                 {
2593                         /* The instruction writes a field in an uninitialized object. */
2594                         /* This is only allowed when a field of an uninitialized 'this' object is */
2595                         /* written inside an initialization method                                */
2596
2597                         classinfo *initclass;
2598                         instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2599
2600                         if (ins != NULL) {
2601                                 exceptions_throw_verifyerror(refmethod, 
2602                                                 "accessing field of uninitialized object");
2603                                 return false;
2604                         }
2605                         /* XXX check that class of field == refmethod->clazz */
2606                         initclass = refmethod->clazz; /* XXX classrefs */
2607                         assert(initclass->state & CLASS_LOADED);
2608                         assert(initclass->state & CLASS_LINKED);
2609
2610                         typeinfo_init_classinfo(&tinfo, initclass);
2611                         insttip = &tinfo;
2612                 }
2613                 else {
2614                         insttip = instanceti;
2615                 }
2616                 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2617                                         &(ref->instancetypes), insttip, 
2618                                         FIELDREF_CLASSNAME(fieldref)))
2619                         return false;
2620         }
2621         else {
2622                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2623         }
2624
2625         /* record subtype constraints for the value type, if any */
2626         type = fd->type;
2627         if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2628                 assert(valueti);
2629                 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2630                                         &(ref->valueconstraints), valueti, 
2631                                         fieldref->parseddesc.fd->classref->name))
2632                         return false;
2633         }
2634         else {
2635                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2636         }
2637
2638         return true;
2639 }
2640 #endif /* ENABLE_VERIFIER */
2641
2642 /* resolve_create_unresolved_method ********************************************
2643  
2644    Create an unresolved_method struct for the given method invocation
2645   
2646    IN:
2647        referer..........the class containing the reference
2648            refmethod........the method triggering the resolution (if any)
2649            iptr.............the INVOKE* instruction
2650
2651    RETURN VALUE:
2652        a pointer to a new unresolved_method struct
2653
2654 *******************************************************************************/
2655
2656 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2657                                                                                                          methodinfo *refmethod,
2658                                                                                                          constant_FMIref *methodref,
2659                                                                                                          bool invokestatic,
2660                                                                                                          bool invokespecial)
2661 {
2662         unresolved_method *ref;
2663
2664         assert(methodref);
2665
2666 #ifdef RESOLVE_VERBOSE
2667         printf("create_unresolved_method\n");
2668         printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2669         printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2670         printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2671         printf("    name   : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2672         printf("    desc   : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2673 #endif
2674
2675         /* allocate params if necessary */
2676         descriptor_params_from_paramtypes(
2677                 methodref->parseddesc.md,
2678                 (invokestatic) ? ACC_STATIC : ACC_NONE);
2679
2680         /* create the data structure */
2681         ref = NEW(unresolved_method);
2682         ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2683                            | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2684         ref->referermethod = refmethod;
2685         ref->methodref = methodref;
2686         ref->paramconstraints = NULL;
2687         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2688
2689         return ref;
2690 }
2691
2692
2693 /* resolve_constrain_unresolved_method_instance ********************************
2694  
2695    Record subtype constraints for the instance argument of a method call.
2696   
2697    IN:
2698        ref..............the unresolved_method structure of the call
2699        referer..........the class containing the reference
2700            refmethod........the method triggering the resolution (if any)
2701            iptr.............the INVOKE* instruction
2702
2703    RETURN VALUE:
2704        true.............everything ok
2705            false............an exception has been thrown
2706
2707 *******************************************************************************/
2708
2709 #if defined(ENABLE_VERIFIER)
2710 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2711                                                                                                   methodinfo *refmethod,
2712                                                                                                   typeinfo_t *instanceti,
2713                                                                                                   bool invokespecial)
2714 {
2715         constant_FMIref   *methodref;
2716         constant_classref *instanceref;
2717         typeinfo_t           tinfo;
2718         typeinfo_t          *tip;
2719
2720         assert(ref);
2721         methodref = ref->methodref;
2722         assert(methodref);
2723
2724         /* XXX clean this up */
2725         instanceref = IS_FMIREF_RESOLVED(methodref)
2726                 ? class_get_self_classref(methodref->p.method->clazz)
2727                 : methodref->p.classref;
2728
2729 #ifdef RESOLVE_VERBOSE
2730         printf("resolve_constrain_unresolved_method_instance\n");
2731         printf("    rmethod: "); method_println(refmethod);
2732         printf("    mref   : "); method_methodref_println(methodref);
2733 #endif
2734
2735         /* record subtype constraints for the instance type, if any */
2736
2737         if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2738         {   /* XXX clean up */
2739                 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2740                 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2741                                                                          : CLASSREF_OR_CLASSINFO(refmethod->clazz);
2742                 tip = &tinfo;
2743                 if (!typeinfo_init_class(tip, initclass))
2744                         return false;
2745         }
2746         else {
2747                 tip = instanceti;
2748         }
2749
2750         if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2751                                 &(ref->instancetypes),tip,instanceref->name))
2752                 return false;
2753
2754         return true;
2755 }
2756 #endif /* defined(ENABLE_VERIFIER) */
2757
2758
2759 /* resolve_constrain_unresolved_method_params  *********************************
2760  
2761    Record subtype constraints for the non-instance arguments of a method call.
2762   
2763    IN:
2764        jd...............current jitdata (for looking up variables)
2765        ref..............the unresolved_method structure of the call
2766            refmethod........the method triggering the resolution (if any)
2767            iptr.............the INVOKE* instruction
2768
2769    RETURN VALUE:
2770        true.............everything ok
2771            false............an exception has been thrown
2772
2773 *******************************************************************************/
2774
2775 #if defined(ENABLE_VERIFIER)
2776 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2777                                                                                                 unresolved_method *ref,
2778                                                                                                 methodinfo *refmethod,
2779                                                                                                 instruction *iptr)
2780 {
2781         constant_FMIref *methodref;
2782         varinfo *param;
2783         methoddesc *md;
2784         int i,j;
2785         int type;
2786         int instancecount;
2787
2788         assert(ref);
2789         methodref = ref->methodref;
2790         assert(methodref);
2791         md = methodref->parseddesc.md;
2792         assert(md);
2793         assert(md->params != NULL);
2794
2795 #ifdef RESOLVE_VERBOSE
2796         printf("resolve_constrain_unresolved_method_params\n");
2797         printf("    rmethod: "); method_println(refmethod);
2798         printf("    mref   : "); method_methodref_println(methodref);
2799 #endif
2800
2801         instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2802
2803         /* record subtype constraints for the parameter types, if any */
2804
2805         for (i=md->paramcount-1-instancecount; i>=0; --i) {
2806                 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2807                 type = md->paramtypes[i+instancecount].type;
2808
2809                 assert(param);
2810                 assert(type == param->type);
2811
2812                 if (type == TYPE_ADR) {
2813                         if (!ref->paramconstraints) {
2814                                 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2815                                 for (j=md->paramcount-1-instancecount; j>i; --j)
2816                                         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2817                         }
2818                         assert(ref->paramconstraints);
2819                         if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2820                                                 ref->paramconstraints + i,&(param->typeinfo),
2821                                                 md->paramtypes[i+instancecount].classref->name))
2822                                 return false;
2823                 }
2824                 else {
2825                         if (ref->paramconstraints)
2826                                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2827                 }
2828         }
2829
2830         return true;
2831 }
2832 #endif /* ENABLE_VERIFIER */
2833
2834
2835 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2836  
2837    Record subtype constraints for the non-instance arguments of a method call.
2838   
2839    IN:
2840        ref..............the unresolved_method structure of the call
2841            refmethod........the method triggering the resolution (if any)
2842            stack............TOS before the INVOKE instruction
2843
2844    RETURN VALUE:
2845        true.............everything ok
2846            false............an exception has been thrown
2847
2848 *******************************************************************************/
2849
2850 #if defined(ENABLE_VERIFIER)
2851 bool resolve_constrain_unresolved_method_params_stackbased(
2852                 unresolved_method *ref,
2853                 methodinfo *refmethod,
2854                 typedescriptor_t *stack)
2855 {
2856         constant_FMIref *methodref;
2857         typedescriptor_t *param;
2858         methoddesc *md;
2859         int i,j;
2860         int type;
2861         int instancecount;
2862
2863         assert(ref);
2864         methodref = ref->methodref;
2865         assert(methodref);
2866         md = methodref->parseddesc.md;
2867         assert(md);
2868         assert(md->params != NULL);
2869
2870 #ifdef RESOLVE_VERBOSE
2871         printf("resolve_constrain_unresolved_method_params_stackbased\n");
2872         printf("    rmethod: "); method_println(refmethod);
2873         printf("    mref   : "); method_methodref_println(methodref);
2874 #endif
2875
2876         instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2877
2878         /* record subtype constraints for the parameter types, if any */
2879
2880         param = stack - (md->paramslots - 1 - instancecount);
2881
2882         for (i = instancecount; i < md->paramcount; ++i) {
2883                 type = md->paramtypes[i].type;
2884
2885                 assert(type == param->type);
2886
2887                 if (type == TYPE_ADR) {
2888                         if (!ref->paramconstraints) {
2889                                 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2890                                 for (j = 0; j < i - instancecount; ++j)
2891                                         UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2892                         }
2893                         assert(ref->paramconstraints);
2894                         if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2895                                                 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2896                                                 md->paramtypes[i].classref->name))
2897                                 return false;
2898                 }
2899                 else {
2900                         if (ref->paramconstraints)
2901                                 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2902                 }
2903
2904                 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2905         }
2906
2907         return true;
2908 }
2909 #endif /* ENABLE_VERIFIER */
2910
2911
2912 /******************************************************************************/
2913 /* FREEING MEMORY                                                             */
2914 /******************************************************************************/
2915
2916 #ifdef ENABLE_VERIFIER
2917 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2918 {
2919         if (list) {
2920                 classref_or_classinfo *p = list;
2921
2922                 /* this is silly. we *only* need to count the elements for MFREE */
2923                 while ((p++)->any)
2924                         ;
2925                 MFREE(list,classref_or_classinfo,(p - list));
2926         }
2927 }
2928 #endif /* ENABLE_VERIFIER */
2929
2930 /* unresolved_class_free *******************************************************
2931  
2932    Free the memory used by an unresolved_class
2933   
2934    IN:
2935        ref..............the unresolved_class
2936
2937 *******************************************************************************/
2938
2939 void unresolved_class_free(unresolved_class *ref)
2940 {
2941         assert(ref);
2942
2943 #ifdef ENABLE_VERIFIER
2944         unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2945 #endif
2946         FREE(ref,unresolved_class);
2947 }
2948
2949 /* unresolved_field_free *******************************************************
2950  
2951    Free the memory used by an unresolved_field
2952   
2953    IN:
2954        ref..............the unresolved_field
2955
2956 *******************************************************************************/
2957
2958 void unresolved_field_free(unresolved_field *ref)
2959 {
2960         assert(ref);
2961
2962 #ifdef ENABLE_VERIFIER
2963         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2964         unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2965 #endif
2966         FREE(ref,unresolved_field);
2967 }
2968
2969 /* unresolved_method_free ******************************************************
2970  
2971    Free the memory used by an unresolved_method
2972   
2973    IN:
2974        ref..............the unresolved_method
2975
2976 *******************************************************************************/
2977
2978 void unresolved_method_free(unresolved_method *ref)
2979 {
2980         assert(ref);
2981
2982 #ifdef ENABLE_VERIFIER
2983         unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2984         if (ref->paramconstraints) {
2985                 int i;
2986                 int count = ref->methodref->parseddesc.md->paramcount;
2987
2988                 for (i=0; i<count; ++i)
2989                         unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2990                 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2991         }
2992 #endif
2993         FREE(ref,unresolved_method);
2994 }
2995
2996 /******************************************************************************/
2997 /* DEBUG DUMPS                                                                */
2998 /******************************************************************************/
2999
3000 #if !defined(NDEBUG)
3001
3002 /* unresolved_subtype_set_debug_dump *******************************************
3003  
3004    Print debug info for unresolved_subtype_set to stream
3005   
3006    IN:
3007        stset............the unresolved_subtype_set
3008            file.............the stream
3009
3010 *******************************************************************************/
3011
3012 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
3013 {
3014         classref_or_classinfo *p;
3015
3016         if (SUBTYPESET_IS_EMPTY(*stset)) {
3017                 fprintf(file,"        (empty)\n");
3018         }
3019         else {
3020                 p = stset->subtyperefs;
3021                 for (;p->any; ++p) {
3022                         if (IS_CLASSREF(*p)) {
3023                                 fprintf(file,"        ref: ");
3024                                 utf_fprint_printable_ascii(file,p->ref->name);
3025                         }
3026                         else {
3027                                 fprintf(file,"        cls: ");
3028                                 utf_fprint_printable_ascii(file,p->cls->name);
3029                         }
3030                         fputc('\n',file);
3031                 }
3032         }
3033 }
3034
3035 /* unresolved_class_debug_dump *************************************************
3036  
3037    Print debug info for unresolved_class to stream
3038   
3039    IN:
3040        ref..............the unresolved_class
3041            file.............the stream
3042
3043 *******************************************************************************/
3044
3045 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3046 {
3047         fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3048         if (ref) {
3049                 fprintf(file,"    referer   : ");
3050                 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3051                 fprintf(file,"    refmethod : ");
3052                 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3053                 fprintf(file,"    refmethodd: ");
3054                 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3055                 fprintf(file,"    classname : ");
3056                 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3057                 fprintf(file,"    subtypeconstraints:\n");
3058                 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3059         }
3060 }
3061
3062 /* unresolved_field_debug_dump *************************************************
3063  
3064    Print debug info for unresolved_field to stream
3065   
3066    IN:
3067        ref..............the unresolved_field
3068            file.............the stream
3069
3070 *******************************************************************************/
3071
3072 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3073 {
3074         fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3075         if (ref) {
3076                 fprintf(file,"    referer   : ");
3077                 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3078                 fprintf(file,"    refmethod : ");
3079                 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3080                 fprintf(file,"    refmethodd: ");
3081                 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3082                 fprintf(file,"    classname : ");
3083                 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3084                 fprintf(file,"    name      : ");
3085                 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3086                 fprintf(file,"    descriptor: ");
3087                 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3088                 fprintf(file,"    parseddesc: ");
3089                 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3090                 fprintf(file,"    flags     : %04x\n",ref->flags);
3091                 fprintf(file,"    instancetypes:\n");
3092                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3093                 fprintf(file,"    valueconstraints:\n");
3094                 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3095         }
3096 }
3097
3098 /* unresolved_method_debug_dump ************************************************
3099  
3100    Print debug info for unresolved_method to stream
3101   
3102    IN:
3103        ref..............the unresolved_method
3104            file.............the stream
3105
3106 *******************************************************************************/
3107
3108 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3109 {
3110         int i;
3111
3112         fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3113         if (ref) {
3114                 fprintf(file,"    referer   : ");
3115                 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3116                 fprintf(file,"    refmethod : ");
3117                 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3118                 fprintf(file,"    refmethodd: ");
3119                 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3120                 fprintf(file,"    classname : ");
3121                 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3122                 fprintf(file,"    name      : ");
3123                 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3124                 fprintf(file,"    descriptor: ");
3125                 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3126                 fprintf(file,"    parseddesc: ");
3127                 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3128                 fprintf(file,"    flags     : %04x\n",ref->flags);
3129                 fprintf(file,"    instancetypes:\n");
3130                 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3131                 fprintf(file,"    paramconstraints:\n");
3132                 if (ref->paramconstraints) {
3133                         for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3134                                 fprintf(file,"      param %d:\n",i);
3135                                 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3136                         }
3137                 }
3138                 else {
3139                         fprintf(file,"      (empty)\n");
3140                 }
3141         }
3142 }
3143 #endif /* !defined(NDEBUG) */
3144
3145
3146 /*
3147  * These are local overrides for various environment variables in Emacs.
3148  * Please do not remove this and leave it at the end of the file, where
3149  * Emacs will automagically detect them.
3150  * ---------------------------------------------------------------------
3151  * Local variables:
3152  * mode: c
3153  * indent-tabs-mode: t
3154  * c-basic-offset: 4
3155  * tab-width: 4
3156  * End:
3157  * vim:noexpandtab:sw=4:ts=4:
3158  */