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