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