1 /* src/vm/resolve.c - resolving classes/interfaces/fields/methods
3 Copyright (C) 1996-2005, 2006, 2007 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
8 This file is part of CACAO.
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.
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.
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
25 $Id: resolve.c 7486 2007-03-08 13:50:07Z twisti $
36 #include "mm/memory.h"
38 #include "vm/access.h"
39 #include "vm/exceptions.h"
40 #include "vm/global.h"
42 #include "vm/jit/jit.h"
43 #include "vm/jit/verify/typeinfo.h"
45 #include "vmcore/classcache.h"
46 #include "vmcore/descriptor.h"
47 #include "vmcore/linker.h"
48 #include "vmcore/loader.h"
49 #include "vmcore/options.h"
50 #include "vm/resolve.h"
53 /******************************************************************************/
55 /******************************************************************************/
57 /*#define RESOLVE_VERBOSE*/
59 /******************************************************************************/
60 /* CLASS RESOLUTION */
61 /******************************************************************************/
63 /* resolve_class_from_name *****************************************************
65 Resolve a symbolic class reference
68 referer..........the class containing the reference
69 refmethod........the method from which resolution was triggered
70 (may be NULL if not applicable)
71 classname........class name to resolve
72 mode.............mode of resolution:
73 resolveLazy...only resolve if it does not
74 require loading classes
75 resolveEager..load classes if necessary
76 checkaccess......if true, access rights to the class are checked
77 link.............if true, guarantee that the returned class, if any,
81 *result..........set to result of resolution, or to NULL if
82 the reference has not been resolved
83 In the case of an exception, *result is
84 guaranteed to be set to NULL.
87 true.............everything ok
88 (*result may still be NULL for resolveLazy)
89 false............an exception has been thrown
92 The returned class is *not* guaranteed to be linked!
93 (It is guaranteed to be loaded, though.)
95 *******************************************************************************/
97 bool resolve_class_from_name(classinfo *referer,
98 methodinfo *refmethod,
105 classinfo *cls = NULL;
112 assert(mode == resolveLazy || mode == resolveEager);
116 #ifdef RESOLVE_VERBOSE
117 printf("resolve_class_from_name(");
118 utf_fprint_printable_ascii(stdout,referer->name);
119 printf(",%p,",(void*)referer->classloader);
120 utf_fprint_printable_ascii(stdout,classname);
121 printf(",%d,%d)\n",(int)checkaccess,(int)link);
124 /* lookup if this class has already been loaded */
126 cls = classcache_lookup(referer->classloader, classname);
128 #ifdef RESOLVE_VERBOSE
129 printf(" lookup result: %p\n",(void*)cls);
133 /* resolve array types */
135 if (classname->text[0] == '[') {
136 utf_ptr = classname->text + 1;
137 len = classname->blength - 1;
139 /* classname is an array type name */
147 /* the component type is a reference type */
148 /* resolve the component type */
149 if (!resolve_class_from_name(referer,refmethod,
150 utf_new(utf_ptr,len),
151 mode,checkaccess,link,&cls))
152 return false; /* exception */
154 assert(mode == resolveLazy);
155 return true; /* be lazy */
157 /* create the array class */
158 cls = class_array_of(cls,false);
160 return false; /* exception */
164 /* the class has not been loaded, yet */
165 if (mode == resolveLazy)
166 return true; /* be lazy */
169 #ifdef RESOLVE_VERBOSE
170 printf(" loading...\n");
175 if (!(cls = load_class_from_classloader(classname,
176 referer->classloader)))
177 return false; /* exception */
181 /* the class is now loaded */
183 assert(cls->state & CLASS_LOADED);
185 #ifdef RESOLVE_VERBOSE
186 printf(" checking access rights...\n");
189 /* check access rights of referer to refered class */
190 if (checkaccess && !access_is_accessible_class(referer,cls)) {
194 msglen = utf_bytes(cls->name) + utf_bytes(referer->name) + 100;
195 message = MNEW(char, msglen);
196 strcpy(message, "class is not accessible (");
197 utf_cat_classname(message, cls->name);
198 strcat(message, " from ");
199 utf_cat_classname(message, referer->name);
200 strcat(message, ")");
202 exceptions_throw_illegalaccessexception(message);
204 MFREE(message, char, msglen);
206 return false; /* exception */
209 /* link the class if necessary */
211 if (!(cls->state & CLASS_LINKED))
212 if (!link_class(cls))
213 return false; /* exception */
215 assert(cls->state & CLASS_LINKED);
218 /* resolution succeeds */
219 #ifdef RESOLVE_VERBOSE
220 printf(" success.\n");
226 /* resolve_classref ************************************************************
228 Resolve a symbolic class reference
231 refmethod........the method from which resolution was triggered
232 (may be NULL if not applicable)
233 ref..............class reference
234 mode.............mode of resolution:
235 resolveLazy...only resolve if it does not
236 require loading classes
237 resolveEager..load classes if necessary
238 checkaccess......if true, access rights to the class are checked
239 link.............if true, guarantee that the returned class, if any,
243 *result..........set to result of resolution, or to NULL if
244 the reference has not been resolved
245 In the case of an exception, *result is
246 guaranteed to be set to NULL.
249 true.............everything ok
250 (*result may still be NULL for resolveLazy)
251 false............an exception has been thrown
253 *******************************************************************************/
255 bool resolve_classref(methodinfo *refmethod,
256 constant_classref *ref,
262 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
265 /* resolve_classref_or_classinfo ***********************************************
267 Resolve a symbolic class reference if necessary
269 NOTE: If given, refmethod->class is used as the referring class.
270 Otherwise, cls.ref->referer is used.
273 refmethod........the method from which resolution was triggered
274 (may be NULL if not applicable)
275 cls..............class reference or classinfo
276 mode.............mode of resolution:
277 resolveLazy...only resolve if it does not
278 require loading classes
279 resolveEager..load classes if necessary
280 checkaccess......if true, access rights to the class are checked
281 link.............if true, guarantee that the returned class, if any,
285 *result..........set to result of resolution, or to NULL if
286 the reference has not been resolved
287 In the case of an exception, *result is
288 guaranteed to be set to NULL.
291 true.............everything ok
292 (*result may still be NULL for resolveLazy)
293 false............an exception has been thrown
295 *******************************************************************************/
297 bool resolve_classref_or_classinfo(methodinfo *refmethod,
298 classref_or_classinfo cls,
308 assert(mode == resolveEager || mode == resolveLazy);
311 #ifdef RESOLVE_VERBOSE
312 printf("resolve_classref_or_classinfo(");
313 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
314 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
319 if (IS_CLASSREF(cls)) {
320 /* we must resolve this reference */
322 /* determine which class to use as the referer */
324 /* Common cases are refmethod == NULL or both referring classes */
325 /* being the same, so the referer usually is cls.ref->referer. */
326 /* There is one important case where it is not: When we do a */
327 /* deferred assignability check to a formal argument of a method, */
328 /* we must use refmethod->class (the caller's class) to resolve */
329 /* the type of the formal argument. */
331 referer = (refmethod) ? refmethod->class : cls.ref->referer;
333 if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
334 mode, checkaccess, link, &c))
335 goto return_exception;
338 /* cls has already been resolved */
340 assert(c->state & CLASS_LOADED);
342 assert(c || (mode == resolveLazy));
345 return true; /* be lazy */
348 assert(c->state & CLASS_LOADED);
351 if (!(c->state & CLASS_LINKED))
353 goto return_exception;
355 assert(c->state & CLASS_LINKED);
368 /* resolve_classref_or_classinfo_eager *****************************************
370 Resolve a symbolic class reference eagerly if necessary.
371 No attempt is made to link the class.
374 cls..............class reference or classinfo
375 checkaccess......if true, access rights to the class are checked
378 classinfo *......the resolved class
379 NULL.............an exception has been thrown
381 *******************************************************************************/
383 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
388 if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
395 /* resolve_class_from_typedesc *************************************************
397 Return a classinfo * for the given type descriptor
400 d................type descriptor
401 checkaccess......if true, access rights to the class are checked
402 link.............if true, guarantee that the returned class, if any,
405 *result..........set to result of resolution, or to NULL if
406 the reference has not been resolved
407 In the case of an exception, *result is
408 guaranteed to be set to NULL.
411 true.............everything ok
412 false............an exception has been thrown
415 This function always resolves eagerly.
417 *******************************************************************************/
419 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
428 #ifdef RESOLVE_VERBOSE
429 printf("resolve_class_from_typedesc(");
430 descriptor_debug_print_typedesc(stdout,d);
431 printf(",%i,%i)\n",(int)checkaccess,(int)link);
434 if (d->type == TYPE_ADR) {
435 /* a reference type */
437 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
438 resolveEager,checkaccess,link,&cls))
439 return false; /* exception */
442 /* a primitive type */
443 cls = primitivetype_table[d->decltype].class_primitive;
444 assert(cls->state & CLASS_LOADED);
445 if (!(cls->state & CLASS_LINKED))
446 if (!link_class(cls))
447 return false; /* exception */
450 assert(cls->state & CLASS_LOADED);
451 assert(!link || (cls->state & CLASS_LINKED));
453 #ifdef RESOLVE_VERBOSE
454 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
461 /******************************************************************************/
462 /* SUBTYPE SET CHECKS */
463 /******************************************************************************/
465 /* resolve_subtype_check *******************************************************
467 Resolve the given types lazily and perform a subtype check
470 refmethod........the method triggering the resolution
471 subtype..........checked to be a subtype of supertype
472 supertype........the super type to check agaings
473 mode.............mode of resolution:
474 resolveLazy...only resolve if it does not
475 require loading classes
476 resolveEager..load classes if necessary
477 error............which type of exception to throw if
478 the test fails. May be:
479 resolveLinkageError, or
480 resolveIllegalAccessError
481 IMPORTANT: If error==resolveIllegalAccessError,
482 then array types are not checked.
485 resolveSucceeded.....the check succeeded
486 resolveDeferred......the check could not be performed due to
487 unresolved types. (This can only happen for
488 mode == resolveLazy.)
489 resolveFailed........the check failed, an exception has been thrown.
492 The types are resolved first, so any
493 exception which may occurr during resolution may
494 be thrown by this function.
496 *******************************************************************************/
498 #if defined(ENABLE_VERIFIER)
499 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
500 classref_or_classinfo subtype,
501 classref_or_classinfo supertype,
511 assert(supertype.any);
512 assert(mode == resolveLazy || mode == resolveEager);
513 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
515 /* resolve the subtype */
517 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
518 /* the subclass could not be resolved. therefore we are sure that */
519 /* no instances of this subclass will ever exist -> skip this test */
520 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
521 exceptions_clear_exception();
522 return resolveSucceeded;
525 return resolveDeferred; /* be lazy */
527 assert(subclass->state & CLASS_LINKED);
529 /* do not check access to protected members of arrays */
531 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
532 return resolveSucceeded;
535 /* perform the subtype check */
537 typeinfo_init_classinfo(&subti,subclass);
539 r = typeinfo_is_assignable_to_class(&subti,supertype);
540 if (r == typecheck_FAIL)
541 return resolveFailed; /* failed, exception is already set */
543 if (r == typecheck_MAYBE) {
544 assert(IS_CLASSREF(supertype));
545 if (mode == resolveEager) {
546 if (!resolve_classref_or_classinfo(refmethod,supertype,
547 resolveEager,false,true,
550 return resolveFailed;
552 assert(supertype.cls);
556 return resolveDeferred; /* be lazy */
560 /* sub class relationship is false */
565 #if defined(RESOLVE_VERBOSE)
566 printf("SUBTYPE CHECK FAILED!\n");
570 utf_bytes(subclass->name) +
571 utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
574 message = MNEW(char, msglen);
576 strcpy(message, (error == resolveIllegalAccessError) ?
577 "illegal access to protected member ("
578 : "subtype constraint violated (");
580 utf_cat_classname(message, subclass->name);
581 strcat(message, " is not a subclass of ");
582 utf_cat_classname(message, CLASSREF_OR_CLASSINFO_NAME(supertype));
583 strcat(message, ")");
585 if (error == resolveIllegalAccessError)
586 exceptions_throw_illegalaccessexception(message);
588 exceptions_throw_linkageerror(message, NULL);
590 MFREE(message, char, msglen);
592 return resolveFailed; /* exception */
597 return resolveSucceeded;
599 #endif /* defined(ENABLE_VERIFIER) */
601 /* resolve_lazy_subtype_checks *************************************************
603 Resolve the types to check lazily and perform subtype checks
606 refmethod........the method triggering the resolution
607 subtinfo.........the typeinfo containing the subtypes
608 supertype........the supertype to test againgst
609 mode.............mode of resolution:
610 resolveLazy...only resolve if it does not
611 require loading classes
612 resolveEager..load classes if necessary
613 error............which type of exception to throw if
614 the test fails. May be:
615 resolveLinkageError, or
616 resolveIllegalAccessError
617 IMPORTANT: If error==resolveIllegalAccessError,
618 then array types in the set are skipped.
621 resolveSucceeded.....the check succeeded
622 resolveDeferred......the check could not be performed due to
624 resolveFailed........the check failed, an exception has been thrown.
627 The references in the set are resolved first, so any
628 exception which may occurr during resolution may
629 be thrown by this function.
631 *******************************************************************************/
633 #if defined(ENABLE_VERIFIER)
634 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
636 classref_or_classinfo supertype,
641 resolve_result_t result;
645 assert(supertype.any);
646 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
648 /* returnAddresses are illegal here */
650 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
651 exceptions_throw_verifyerror(refmethod,
652 "Invalid use of returnAddress");
653 return resolveFailed;
656 /* uninitialized objects are illegal here */
658 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
659 exceptions_throw_verifyerror(refmethod,
660 "Invalid use of uninitialized object");
661 return resolveFailed;
664 /* the nulltype is always assignable */
666 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
667 return resolveSucceeded;
669 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
671 if (supertype.cls == class_java_lang_Object
672 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
673 && refmethod->class->classloader == NULL))
675 return resolveSucceeded;
678 if (subtinfo->merged) {
680 /* for a merged type we have to do a series of checks */
682 count = subtinfo->merged->count;
683 for (i=0; i<count; ++i) {
684 classref_or_classinfo c = subtinfo->merged->list[i];
685 if (subtinfo->dimension > 0) {
686 /* a merge of array types */
687 /* the merged list contains the possible _element_ types, */
688 /* so we have to create array types with these elements. */
689 if (IS_CLASSREF(c)) {
690 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
693 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
697 /* do the subtype check against the type c */
699 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
700 if (result != resolveSucceeded)
706 /* a single type, this is the common case, hopefully */
708 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
709 == CLASSREF_OR_CLASSINFO_NAME(supertype))
711 /* the class names are the same */
712 /* equality is guaranteed by the loading constraints */
713 return resolveSucceeded;
717 /* some other type name, try to perform the check lazily */
719 return resolve_subtype_check(refmethod,
720 subtinfo->typeclass,supertype,
727 return resolveSucceeded;
729 #endif /* defined(ENABLE_VERIFIER) */
731 /* resolve_and_check_subtype_set ***********************************************
733 Resolve the references in the given set and test subtype relationships
736 refmethod........the method triggering the resolution
737 ref..............a set of class/interface references
739 typeref..........the type to test against the set
740 mode.............mode of resolution:
741 resolveLazy...only resolve if it does not
742 require loading classes
743 resolveEager..load classes if necessary
744 error............which type of exception to throw if
745 the test fails. May be:
746 resolveLinkageError, or
747 resolveIllegalAccessError
748 IMPORTANT: If error==resolveIllegalAccessError,
749 then array types in the set are skipped.
752 resolveSucceeded.....the check succeeded
753 resolveDeferred......the check could not be performed due to
754 unresolved types. (This can only happen if
755 mode == resolveLazy.)
756 resolveFailed........the check failed, an exception has been thrown.
759 The references in the set are resolved first, so any
760 exception which may occurr during resolution may
761 be thrown by this function.
763 *******************************************************************************/
765 #if defined(ENABLE_VERIFIER)
766 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
767 unresolved_subtype_set *ref,
768 classref_or_classinfo typeref,
772 classref_or_classinfo *setp;
773 typecheck_result checkresult;
778 assert(mode == resolveLazy || mode == resolveEager);
779 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
781 #if defined(RESOLVE_VERBOSE)
782 printf("resolve_and_check_subtype_set:\n");
783 unresolved_subtype_set_debug_dump(ref, stdout);
784 if (IS_CLASSREF(typeref))
785 class_classref_println(typeref.ref);
787 class_println(typeref.cls);
790 setp = ref->subtyperefs;
792 /* an empty set of tests always succeeds */
793 if (!setp || !setp->any) {
794 return resolveSucceeded;
797 /* first resolve the type if necessary */
798 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
799 return resolveFailed; /* exception */
801 return resolveDeferred; /* be lazy */
803 assert(typeref.cls->state & CLASS_LINKED);
805 /* iterate over the set members */
807 for (; setp->any; ++setp) {
808 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
809 #if defined(RESOLVE_VERBOSE)
810 if (checkresult != resolveSucceeded)
811 printf("SUBTYPE CHECK FAILED!\n");
813 if (checkresult != resolveSucceeded)
818 return resolveSucceeded;
820 #endif /* defined(ENABLE_VERIFIER) */
822 /******************************************************************************/
823 /* CLASS RESOLUTION */
824 /******************************************************************************/
826 /* resolve_class ***************************************************************
828 Resolve an unresolved class reference. The class is also linked.
831 ref..............struct containing the reference
832 mode.............mode of resolution:
833 resolveLazy...only resolve if it does not
834 require loading classes
835 resolveEager..load classes if necessary
836 checkaccess......if true, access rights to the class are checked
839 *result..........set to the result of resolution, or to NULL if
840 the reference has not been resolved
841 In the case of an exception, *result is
842 guaranteed to be set to NULL.
845 true.............everything ok
846 (*result may still be NULL for resolveLazy)
847 false............an exception has been thrown
849 *******************************************************************************/
851 #ifdef ENABLE_VERIFIER
852 bool resolve_class(unresolved_class *ref,
858 resolve_result_t checkresult;
862 assert(mode == resolveLazy || mode == resolveEager);
866 #ifdef RESOLVE_VERBOSE
867 unresolved_class_debug_dump(ref,stdout);
870 /* first we must resolve the class */
871 if (!resolve_classref(ref->referermethod,
872 ref->classref,mode,checkaccess,true,&cls))
874 /* the class reference could not be resolved */
875 return false; /* exception */
878 return true; /* be lazy */
881 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
883 /* now we check the subtype constraints */
885 checkresult = resolve_and_check_subtype_set(ref->referermethod,
886 &(ref->subtypeconstraints),
887 CLASSREF_OR_CLASSINFO(cls),
889 resolveLinkageError);
890 if (checkresult != resolveSucceeded)
891 return (bool) checkresult;
897 #endif /* ENABLE_VERIFIER */
899 /* resolve_classref_eager ******************************************************
901 Resolve an unresolved class reference eagerly. The class is also linked and
902 access rights to the class are checked.
905 ref..............constant_classref to the class
908 classinfo * to the class, or
909 NULL if an exception has been thrown
911 *******************************************************************************/
913 classinfo * resolve_classref_eager(constant_classref *ref)
917 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
923 /* resolve_classref_eager_nonabstract ******************************************
925 Resolve an unresolved class reference eagerly. The class is also linked and
926 access rights to the class are checked. A check is performed that the class
930 ref..............constant_classref to the class
933 classinfo * to the class, or
934 NULL if an exception has been thrown
936 *******************************************************************************/
938 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
942 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
945 /* ensure that the class is not abstract */
947 if (c->flags & ACC_ABSTRACT) {
948 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
955 /* resolve_class_eager *********************************************************
957 Resolve an unresolved class reference eagerly. The class is also linked and
958 access rights to the class are checked.
961 ref..............struct containing the reference
964 classinfo * to the class, or
965 NULL if an exception has been thrown
967 *******************************************************************************/
969 #ifdef ENABLE_VERIFIER
970 classinfo * resolve_class_eager(unresolved_class *ref)
974 if (!resolve_class(ref,resolveEager,true,&c))
979 #endif /* ENABLE_VERIFIER */
981 /* resolve_class_eager_no_access_check *****************************************
983 Resolve an unresolved class reference eagerly. The class is also linked.
984 Access rights are _not_ checked.
987 ref..............struct containing the reference
990 classinfo * to the class, or
991 NULL if an exception has been thrown
993 *******************************************************************************/
995 #ifdef ENABLE_VERIFIER
996 classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
1000 if (!resolve_class(ref, resolveEager, false, &c))
1005 #endif /* ENABLE_VERIFIER */
1007 /******************************************************************************/
1008 /* FIELD RESOLUTION */
1009 /******************************************************************************/
1011 /* resolve_field_verifier_checks *******************************************
1013 Do the verifier checks necessary after field has been resolved.
1016 refmethod........the method containing the reference
1017 fieldref.........the field reference
1018 container........the class where the field was found
1019 fi...............the fieldinfo of the resolved field
1020 instanceti.......instance typeinfo, if available
1021 valueti..........value typeinfo, if available
1022 isstatic.........true if this is a *STATIC* instruction
1023 isput............true if this is a PUT* instruction
1026 resolveSucceeded....everything ok
1027 resolveDeferred.....tests could not be done, have been deferred
1028 resolveFailed.......exception has been thrown
1030 *******************************************************************************/
1032 #if defined(ENABLE_VERIFIER)
1033 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
1034 constant_FMIref *fieldref,
1035 classinfo *container,
1037 typeinfo *instanceti,
1042 classinfo *declarer;
1044 resolve_result_t result;
1045 constant_classref *fieldtyperef;
1052 /* get the classinfos and the field type */
1054 referer = refmethod->class;
1057 declarer = fi->class;
1059 assert(referer->state & CLASS_LINKED);
1061 fieldtyperef = fieldref->parseddesc.fd->classref;
1066 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1069 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1070 /* a static field is accessed via an instance, or vice versa */
1071 exceptions_throw_incompatibleclasschangeerror(declarer,
1072 (fi->flags & ACC_STATIC)
1073 ? "static field accessed via instance"
1074 : "instance field accessed without instance");
1076 return resolveFailed;
1079 /* check access rights */
1081 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1086 utf_bytes(declarer->name) +
1087 utf_bytes(fi->name) +
1088 utf_bytes(referer->name) +
1091 message = MNEW(char, msglen);
1093 strcpy(message, "field is not accessible (");
1094 utf_cat_classname(message, declarer->name);
1095 strcat(message, ".");
1096 utf_cat(message, fi->name);
1097 strcat(message, " from ");
1098 utf_cat_classname(message, referer->name);
1099 strcat(message, ")");
1101 exceptions_throw_illegalaccessexception(message);
1103 MFREE(message, char, msglen);
1105 return resolveFailed; /* exception */
1108 /* for non-static methods we have to check the constraints on the */
1115 /* The instanceslot must contain a reference to a non-array type */
1117 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1118 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1119 return resolveFailed;
1121 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1122 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1123 return resolveFailed;
1126 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1128 /* The instruction writes a field in an uninitialized object. */
1129 /* This is only allowed when a field of an uninitialized 'this' object is */
1130 /* written inside an initialization method */
1132 classinfo *initclass;
1133 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1136 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1137 return resolveFailed;
1140 /* XXX check that class of field == refmethod->class */
1141 initclass = referer; /* XXX classrefs */
1142 assert(initclass->state & CLASS_LINKED);
1144 typeinfo_init_classinfo(&tinfo, initclass);
1148 insttip = instanceti;
1151 result = resolve_lazy_subtype_checks(refmethod,
1153 CLASSREF_OR_CLASSINFO(container),
1154 resolveLinkageError);
1155 if (result != resolveSucceeded)
1158 /* check protected access */
1160 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1162 result = resolve_lazy_subtype_checks(refmethod,
1164 CLASSREF_OR_CLASSINFO(referer),
1165 resolveIllegalAccessError);
1166 if (result != resolveSucceeded)
1172 /* for PUT* instructions we have to check the constraints on the value type */
1175 assert(fieldtyperef);
1177 /* check subtype constraints */
1178 result = resolve_lazy_subtype_checks(refmethod,
1180 CLASSREF_OR_CLASSINFO(fieldtyperef),
1181 resolveLinkageError);
1183 if (result != resolveSucceeded)
1187 /* impose loading constraint on field type */
1189 if (fi->type == TYPE_ADR) {
1190 assert(fieldtyperef);
1191 if (!classcache_add_constraint(declarer->classloader,
1192 referer->classloader,
1193 fieldtyperef->name))
1194 return resolveFailed;
1197 /* XXX impose loading constraint on instance? */
1200 return resolveSucceeded;
1202 #endif /* defined(ENABLE_VERIFIER) */
1204 /* resolve_field_lazy **********************************************************
1206 Resolve an unresolved field reference lazily
1208 NOTE: This function does NOT do any verification checks. In case of a
1209 successful resolution, you must call resolve_field_verifier_checks
1210 in order to perform the necessary checks!
1213 refmethod........the referer method
1214 fieldref.........the field reference
1217 resolveSucceeded.....the reference has been resolved
1218 resolveDeferred......the resolving could not be performed lazily
1219 resolveFailed........resolving failed, an exception has been thrown.
1221 *******************************************************************************/
1223 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1224 constant_FMIref *fieldref)
1227 classinfo *container;
1232 /* the class containing the reference */
1234 referer = refmethod->class;
1237 /* check if the field itself is already resolved */
1239 if (IS_FMIREF_RESOLVED(fieldref))
1240 return resolveSucceeded;
1242 /* first we must resolve the class containg the field */
1244 /* XXX can/may lazyResolving trigger linking? */
1246 if (!resolve_class_from_name(referer, refmethod,
1247 fieldref->p.classref->name, resolveLazy, true, true, &container))
1249 /* the class reference could not be resolved */
1250 return resolveFailed; /* exception */
1253 return resolveDeferred; /* be lazy */
1255 assert(container->state & CLASS_LINKED);
1257 /* now we must find the declaration of the field in `container`
1258 * or one of its superclasses */
1260 fi = class_resolvefield(container,
1261 fieldref->name, fieldref->descriptor,
1264 /* The field does not exist. But since we were called lazily, */
1265 /* this error must not be reported now. (It will be reported */
1266 /* if eager resolving of this field is ever tried.) */
1268 exceptions_clear_exception();
1269 return resolveDeferred; /* be lazy */
1272 /* cache the result of the resolution */
1274 fieldref->p.field = fi;
1277 return resolveSucceeded;
1280 /* resolve_field ***************************************************************
1282 Resolve an unresolved field reference
1285 ref..............struct containing the reference
1286 mode.............mode of resolution:
1287 resolveLazy...only resolve if it does not
1288 require loading classes
1289 resolveEager..load classes if necessary
1292 *result..........set to the result of resolution, or to NULL if
1293 the reference has not been resolved
1294 In the case of an exception, *result is
1295 guaranteed to be set to NULL.
1298 true.............everything ok
1299 (*result may still be NULL for resolveLazy)
1300 false............an exception has been thrown
1302 *******************************************************************************/
1304 bool resolve_field(unresolved_field *ref,
1305 resolve_mode_t mode,
1309 classinfo *container;
1310 classinfo *declarer;
1311 constant_classref *fieldtyperef;
1313 resolve_result_t checkresult;
1317 assert(mode == resolveLazy || mode == resolveEager);
1321 #ifdef RESOLVE_VERBOSE
1322 unresolved_field_debug_dump(ref,stdout);
1325 /* the class containing the reference */
1327 referer = ref->referermethod->class;
1330 /* check if the field itself is already resolved */
1331 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1332 fi = ref->fieldref->p.field;
1333 container = fi->class;
1334 goto resolved_the_field;
1337 /* first we must resolve the class containg the field */
1338 if (!resolve_class_from_name(referer,ref->referermethod,
1339 ref->fieldref->p.classref->name,mode,true,true,&container))
1341 /* the class reference could not be resolved */
1342 return false; /* exception */
1345 return true; /* be lazy */
1348 assert(container->state & CLASS_LOADED);
1349 assert(container->state & CLASS_LINKED);
1351 /* now we must find the declaration of the field in `container`
1352 * or one of its superclasses */
1354 #ifdef RESOLVE_VERBOSE
1355 printf(" resolving field in class...\n");
1358 fi = class_resolvefield(container,
1359 ref->fieldref->name,ref->fieldref->descriptor,
1362 if (mode == resolveLazy) {
1363 /* The field does not exist. But since we were called lazily, */
1364 /* this error must not be reported now. (It will be reported */
1365 /* if eager resolving of this field is ever tried.) */
1367 exceptions_clear_exception();
1368 return true; /* be lazy */
1371 return false; /* exception */
1374 /* cache the result of the resolution */
1375 ref->fieldref->p.field = fi;
1379 #ifdef ENABLE_VERIFIER
1380 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1381 /* that no missing parts of an instruction will be accessed. */
1383 checkresult = resolve_field_verifier_checks(
1388 NULL, /* instanceti, handled by constraints below */
1389 NULL, /* valueti, handled by constraints below */
1390 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1391 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1393 if (checkresult != resolveSucceeded)
1394 return (bool) checkresult;
1396 declarer = fi->class;
1398 assert(declarer->state & CLASS_LOADED);
1399 assert(declarer->state & CLASS_LINKED);
1401 /* for non-static accesses we have to check the constraints on the */
1404 if (!(ref->flags & RESOLVE_STATIC)) {
1405 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1406 &(ref->instancetypes),
1407 CLASSREF_OR_CLASSINFO(container),
1408 mode, resolveLinkageError);
1409 if (checkresult != resolveSucceeded)
1410 return (bool) checkresult;
1413 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1415 /* for PUT* instructions we have to check the constraints on the value type */
1416 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1417 assert(fieldtyperef);
1418 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1419 /* check subtype constraints */
1420 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1421 &(ref->valueconstraints),
1422 CLASSREF_OR_CLASSINFO(fieldtyperef),
1423 mode, resolveLinkageError);
1424 if (checkresult != resolveSucceeded)
1425 return (bool) checkresult;
1429 /* check protected access */
1430 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1431 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1432 &(ref->instancetypes),
1433 CLASSREF_OR_CLASSINFO(referer),
1435 resolveIllegalAccessError);
1436 if (checkresult != resolveSucceeded)
1437 return (bool) checkresult;
1441 #endif /* ENABLE_VERIFIER */
1449 /* resolve_field_eager *********************************************************
1451 Resolve an unresolved field reference eagerly.
1454 ref..............struct containing the reference
1457 fieldinfo * to the field, or
1458 NULL if an exception has been thrown
1460 *******************************************************************************/
1462 fieldinfo * resolve_field_eager(unresolved_field *ref)
1466 if (!resolve_field(ref,resolveEager,&fi))
1472 /******************************************************************************/
1473 /* METHOD RESOLUTION */
1474 /******************************************************************************/
1476 /* resolve_method_invokespecial_lookup *****************************************
1478 Do the special lookup for methods invoked by INVOKESPECIAL
1481 refmethod........the method containing the reference
1482 mi...............the methodinfo of the resolved method
1485 a methodinfo *...the result of the lookup,
1486 NULL.............an exception has been thrown
1488 *******************************************************************************/
1490 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1493 classinfo *declarer;
1499 /* get referer and declarer classes */
1501 referer = refmethod->class;
1504 declarer = mi->class;
1506 assert(referer->state & CLASS_LINKED);
1508 /* checks for INVOKESPECIAL: */
1509 /* for <init> and methods of the current class we don't need any */
1510 /* special checks. Otherwise we must verify that the called method */
1511 /* belongs to a super class of the current class */
1513 if ((referer != declarer) && (mi->name != utf_init)) {
1514 /* check that declarer is a super class of the current class */
1516 if (!class_issubclass(referer,declarer)) {
1517 exceptions_throw_verifyerror(refmethod,
1518 "INVOKESPECIAL calling non-super class method");
1522 /* if the referer has ACC_SUPER set, we must do the special */
1523 /* lookup starting with the direct super class of referer */
1525 if ((referer->flags & ACC_SUPER) != 0) {
1526 mi = class_resolvemethod(referer->super.cls,
1531 /* the spec calls for an AbstractMethodError in this case */
1533 exceptions_throw_abstractmethoderror();
1544 /* resolve_method_verifier_checks ******************************************
1546 Do the verifier checks necessary after a method has been resolved.
1549 refmethod........the method containing the reference
1550 methodref........the method reference
1551 mi...............the methodinfo of the resolved method
1552 invokestatic.....true if the method is invoked by INVOKESTATIC
1555 resolveSucceeded....everything ok
1556 resolveDeferred.....tests could not be done, have been deferred
1557 resolveFailed.......exception has been thrown
1559 *******************************************************************************/
1561 #if defined(ENABLE_VERIFIER)
1562 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1563 constant_FMIref *methodref,
1567 classinfo *declarer;
1574 #ifdef RESOLVE_VERBOSE
1575 printf("resolve_method_verifier_checks\n");
1576 printf(" flags: %02x\n",mi->flags);
1579 /* get the classinfos and the method descriptor */
1581 referer = refmethod->class;
1584 declarer = mi->class;
1589 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1590 /* a static method is accessed via an instance, or vice versa */
1591 exceptions_throw_incompatibleclasschangeerror(declarer,
1592 (mi->flags & ACC_STATIC)
1593 ? "static method called via instance"
1594 : "instance method called without instance");
1596 return resolveFailed;
1599 /* check access rights */
1601 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1605 /* XXX clean this up. this should be in exceptions.c */
1607 utf_bytes(declarer->name) +
1608 utf_bytes(mi->name) +
1609 utf_bytes(mi->descriptor) +
1610 utf_bytes(referer->name) +
1613 message = MNEW(char, msglen);
1615 strcpy(message, "method is not accessible (");
1616 utf_cat_classname(message, declarer->name);
1617 strcat(message, ".");
1618 utf_cat(message, mi->name);
1619 utf_cat(message, mi->descriptor);
1620 strcat(message, " from ");
1621 utf_cat_classname(message, referer->name);
1622 strcat(message, ")");
1624 exceptions_throw_illegalaccessexception(message);
1626 MFREE(message, char, msglen);
1628 return resolveFailed; /* exception */
1633 return resolveSucceeded;
1635 #endif /* defined(ENABLE_VERIFIER) */
1638 /* resolve_method_instance_type_checks *****************************************
1640 Check the instance type of a method invocation.
1643 refmethod........the method containing the reference
1644 mi...............the methodinfo of the resolved method
1645 instanceti.......typeinfo of the instance slot
1646 invokespecial....true if the method is invoked by INVOKESPECIAL
1649 resolveSucceeded....everything ok
1650 resolveDeferred.....tests could not be done, have been deferred
1651 resolveFailed.......exception has been thrown
1653 *******************************************************************************/
1655 #if defined(ENABLE_VERIFIER)
1656 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1658 typeinfo *instanceti,
1663 resolve_result_t result;
1665 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1666 { /* XXX clean up */
1667 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1668 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1669 : CLASSREF_OR_CLASSINFO(refmethod->class);
1671 if (!typeinfo_init_class(tip, initclass))
1678 result = resolve_lazy_subtype_checks(refmethod,
1680 CLASSREF_OR_CLASSINFO(mi->class),
1681 resolveLinkageError);
1682 if (result != resolveSucceeded)
1685 /* check protected access */
1687 /* XXX use other `declarer` than mi->class? */
1688 if (((mi->flags & ACC_PROTECTED) != 0)
1689 && !SAME_PACKAGE(mi->class, refmethod->class))
1691 result = resolve_lazy_subtype_checks(refmethod,
1693 CLASSREF_OR_CLASSINFO(refmethod->class),
1694 resolveIllegalAccessError);
1695 if (result != resolveSucceeded)
1701 return resolveSucceeded;
1703 #endif /* defined(ENABLE_VERIFIER) */
1706 /* resolve_method_param_type_checks ********************************************
1708 Check non-instance parameter types of a method invocation.
1711 jd...............jitdata of the method doing the call
1712 refmethod........the method containing the reference
1713 iptr.............the invoke instruction
1714 mi...............the methodinfo of the resolved method
1715 invokestatic.....true if the method is invoked by INVOKESTATIC
1718 resolveSucceeded....everything ok
1719 resolveDeferred.....tests could not be done, have been deferred
1720 resolveFailed.......exception has been thrown
1722 *******************************************************************************/
1724 #if defined(ENABLE_VERIFIER)
1725 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1726 methodinfo *refmethod,
1732 resolve_result_t result;
1734 typedesc *paramtypes;
1741 instancecount = (invokestatic) ? 0 : 1;
1743 /* check subtype constraints for TYPE_ADR parameters */
1745 md = mi->parseddesc;
1746 paramtypes = md->paramtypes;
1748 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1749 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1750 type = md->paramtypes[i+instancecount].type;
1753 assert(type == param->type);
1755 if (type == TYPE_ADR) {
1756 result = resolve_lazy_subtype_checks(refmethod,
1758 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1759 resolveLinkageError);
1760 if (result != resolveSucceeded)
1767 return resolveSucceeded;
1769 #endif /* defined(ENABLE_VERIFIER) */
1772 /* resolve_method_param_type_checks_stackbased *********************************
1774 Check non-instance parameter types of a method invocation.
1777 refmethod........the method containing the reference
1778 mi...............the methodinfo of the resolved method
1779 invokestatic.....true if the method is invoked by INVOKESTATIC
1780 stack............TOS before the INVOKE instruction
1783 resolveSucceeded....everything ok
1784 resolveDeferred.....tests could not be done, have been deferred
1785 resolveFailed.......exception has been thrown
1787 *******************************************************************************/
1789 #if defined(ENABLE_VERIFIER)
1790 resolve_result_t resolve_method_param_type_checks_stackbased(
1791 methodinfo *refmethod,
1794 typedescriptor *stack)
1796 typedescriptor *param;
1797 resolve_result_t result;
1799 typedesc *paramtypes;
1804 instancecount = (invokestatic) ? 0 : 1;
1806 /* check subtype constraints for TYPE_ADR parameters */
1808 md = mi->parseddesc;
1809 paramtypes = md->paramtypes;
1811 param = stack - (md->paramslots - 1 - instancecount);
1813 for (i = instancecount; i < md->paramcount; ++i) {
1814 type = md->paramtypes[i].type;
1816 assert(type == param->type);
1818 if (type == TYPE_ADR) {
1819 result = resolve_lazy_subtype_checks(refmethod,
1821 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1822 resolveLinkageError);
1823 if (result != resolveSucceeded)
1827 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1832 return resolveSucceeded;
1834 #endif /* defined(ENABLE_VERIFIER) */
1837 /* resolve_method_loading_constraints ******************************************
1839 Impose loading constraints on the parameters and return type of the
1843 referer..........the class refering to the method
1844 mi...............the method
1847 true................everything ok
1848 false...............an exception has been thrown
1850 *******************************************************************************/
1852 #if defined(ENABLE_VERIFIER)
1853 bool resolve_method_loading_constraints(classinfo *referer,
1857 typedesc *paramtypes;
1862 /* impose loading constraints on parameters (including instance) */
1864 md = mi->parseddesc;
1865 paramtypes = md->paramtypes;
1866 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1868 for (i = 0; i < md->paramcount; i++) {
1869 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1870 if (i < instancecount) {
1871 /* The type of the 'this' pointer is the class containing */
1872 /* the method definition. Since container is the same as, */
1873 /* or a subclass of declarer, we also constrain declarer */
1874 /* by transitivity of loading constraints. */
1875 name = mi->class->name;
1878 name = paramtypes[i].classref->name;
1881 /* The caller (referer) and the callee (container) must agree */
1882 /* on the types of the parameters. */
1883 if (!classcache_add_constraint(referer->classloader,
1884 mi->class->classloader, name))
1885 return false; /* exception */
1889 /* impose loading constraint onto return type */
1891 if (md->returntype.type == TYPE_ADR) {
1892 /* The caller (referer) and the callee (container) must agree */
1893 /* on the return type. */
1894 if (!classcache_add_constraint(referer->classloader,
1895 mi->class->classloader,
1896 md->returntype.classref->name))
1897 return false; /* exception */
1904 #endif /* defined(ENABLE_VERIFIER) */
1907 /* resolve_method_lazy *********************************************************
1909 Resolve an unresolved method reference lazily
1911 NOTE: This function does NOT do any verification checks. In case of a
1912 successful resolution, you must call resolve_method_verifier_checks
1913 in order to perform the necessary checks!
1916 refmethod........the referer method
1917 methodref........the method reference
1918 invokespecial....true if this is an INVOKESPECIAL instruction
1921 resolveSucceeded.....the reference has been resolved
1922 resolveDeferred......the resolving could not be performed lazily
1923 resolveFailed........resolving failed, an exception has been thrown.
1925 *******************************************************************************/
1927 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1928 constant_FMIref *methodref,
1932 classinfo *container;
1937 #ifdef RESOLVE_VERBOSE
1938 printf("resolve_method_lazy\n");
1941 /* the class containing the reference */
1943 referer = refmethod->class;
1946 /* check if the method itself is already resolved */
1948 if (IS_FMIREF_RESOLVED(methodref))
1949 return resolveSucceeded;
1951 /* first we must resolve the class containg the method */
1953 if (!resolve_class_from_name(referer, refmethod,
1954 methodref->p.classref->name, resolveLazy, true, true, &container))
1956 /* the class reference could not be resolved */
1957 return resolveFailed; /* exception */
1960 return resolveDeferred; /* be lazy */
1962 assert(container->state & CLASS_LINKED);
1964 /* now we must find the declaration of the method in `container`
1965 * or one of its superclasses */
1967 if (container->flags & ACC_INTERFACE) {
1968 mi = class_resolveinterfacemethod(container,
1970 methodref->descriptor,
1974 mi = class_resolveclassmethod(container,
1976 methodref->descriptor,
1981 /* The method does not exist. But since we were called lazily, */
1982 /* this error must not be reported now. (It will be reported */
1983 /* if eager resolving of this method is ever tried.) */
1985 exceptions_clear_exception();
1986 return resolveDeferred; /* be lazy */
1989 if (invokespecial) {
1990 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1992 return resolveFailed; /* exception */
1995 /* have the method params already been parsed? no, do it. */
1997 if (!mi->parseddesc->params)
1998 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1999 return resolveFailed;
2001 /* cache the result of the resolution */
2003 methodref->p.method = mi;
2007 return resolveSucceeded;
2010 /* resolve_method **************************************************************
2012 Resolve an unresolved method reference
2015 ref..............struct containing the reference
2016 mode.............mode of resolution:
2017 resolveLazy...only resolve if it does not
2018 require loading classes
2019 resolveEager..load classes if necessary
2022 *result..........set to the result of resolution, or to NULL if
2023 the reference has not been resolved
2024 In the case of an exception, *result is
2025 guaranteed to be set to NULL.
2028 true.............everything ok
2029 (*result may still be NULL for resolveLazy)
2030 false............an exception has been thrown
2032 *******************************************************************************/
2034 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2037 classinfo *container;
2038 classinfo *declarer;
2040 typedesc *paramtypes;
2043 resolve_result_t checkresult;
2047 assert(mode == resolveLazy || mode == resolveEager);
2049 #ifdef RESOLVE_VERBOSE
2050 unresolved_method_debug_dump(ref,stdout);
2055 /* the class containing the reference */
2057 referer = ref->referermethod->class;
2060 /* check if the method itself is already resolved */
2062 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2063 mi = ref->methodref->p.method;
2064 container = mi->class;
2065 goto resolved_the_method;
2068 /* first we must resolve the class containing the method */
2070 if (!resolve_class_from_name(referer,ref->referermethod,
2071 ref->methodref->p.classref->name,mode,true,true,&container))
2073 /* the class reference could not be resolved */
2074 return false; /* exception */
2077 return true; /* be lazy */
2080 assert(container->state & CLASS_LINKED);
2082 /* now we must find the declaration of the method in `container`
2083 * or one of its superclasses */
2085 if (container->flags & ACC_INTERFACE) {
2086 mi = class_resolveinterfacemethod(container,
2087 ref->methodref->name,
2088 ref->methodref->descriptor,
2092 mi = class_resolveclassmethod(container,
2093 ref->methodref->name,
2094 ref->methodref->descriptor,
2099 if (mode == resolveLazy) {
2100 /* The method does not exist. But since we were called lazily, */
2101 /* this error must not be reported now. (It will be reported */
2102 /* if eager resolving of this method is ever tried.) */
2104 exceptions_clear_exception();
2105 return true; /* be lazy */
2108 return false; /* exception */ /* XXX set exceptionptr? */
2111 /* { the method reference has been resolved } */
2113 if (ref->flags & RESOLVE_SPECIAL) {
2114 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2116 return false; /* exception */
2119 /* have the method params already been parsed? no, do it. */
2121 if (!mi->parseddesc->params)
2122 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2125 /* cache the resolution */
2127 ref->methodref->p.method = mi;
2129 resolved_the_method:
2131 #ifdef ENABLE_VERIFIER
2134 checkresult = resolve_method_verifier_checks(
2138 (ref->flags & RESOLVE_STATIC));
2140 if (checkresult != resolveSucceeded)
2141 return (bool) checkresult;
2143 /* impose loading constraints on params and return type */
2145 if (!resolve_method_loading_constraints(referer, mi))
2148 declarer = mi->class;
2150 assert(referer->state & CLASS_LINKED);
2152 /* for non-static methods we have to check the constraints on the */
2155 if (!(ref->flags & RESOLVE_STATIC)) {
2156 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2157 &(ref->instancetypes),
2158 CLASSREF_OR_CLASSINFO(container),
2160 resolveLinkageError);
2161 if (checkresult != resolveSucceeded)
2162 return (bool) checkresult;
2169 /* check subtype constraints for TYPE_ADR parameters */
2171 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2172 paramtypes = mi->parseddesc->paramtypes;
2174 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2175 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2176 if (ref->paramconstraints) {
2177 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2178 ref->paramconstraints + i,
2179 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2181 resolveLinkageError);
2182 if (checkresult != resolveSucceeded)
2183 return (bool) checkresult;
2188 /* check protected access */
2190 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2192 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2193 &(ref->instancetypes),
2194 CLASSREF_OR_CLASSINFO(referer),
2196 resolveIllegalAccessError);
2197 if (checkresult != resolveSucceeded)
2198 return (bool) checkresult;
2201 #endif /* ENABLE_VERIFIER */
2208 /* resolve_method_eager ********************************************************
2210 Resolve an unresolved method reference eagerly.
2213 ref..............struct containing the reference
2216 methodinfo * to the method, or
2217 NULL if an exception has been thrown
2219 *******************************************************************************/
2221 methodinfo * resolve_method_eager(unresolved_method *ref)
2225 if (!resolve_method(ref,resolveEager,&mi))
2231 /******************************************************************************/
2232 /* CREATING THE DATA STRUCTURES */
2233 /******************************************************************************/
2235 #ifdef ENABLE_VERIFIER
2236 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2237 methodinfo *refmethod,
2238 unresolved_subtype_set *stset,
2240 utf *declaredclassname)
2248 #ifdef RESOLVE_VERBOSE
2249 printf("unresolved_subtype_set_from_typeinfo\n");
2250 #ifdef TYPEINFO_DEBUG
2251 typeinfo_print(stdout,tinfo,4);
2253 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2257 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2258 exceptions_throw_verifyerror(refmethod,
2259 "Invalid use of returnAddress");
2263 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2264 exceptions_throw_verifyerror(refmethod,
2265 "Invalid use of uninitialized object");
2269 /* the nulltype is always assignable */
2270 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2273 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2274 if (declaredclassname == utf_java_lang_Object
2275 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2280 if (tinfo->merged) {
2281 count = tinfo->merged->count;
2282 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2283 for (i=0; i<count; ++i) {
2284 classref_or_classinfo c = tinfo->merged->list[i];
2285 if (tinfo->dimension > 0) {
2286 /* a merge of array types */
2287 /* the merged list contains the possible _element_ types, */
2288 /* so we have to create array types with these elements. */
2289 if (IS_CLASSREF(c)) {
2290 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2293 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2296 stset->subtyperefs[i] = c;
2298 stset->subtyperefs[count].any = NULL; /* terminate */
2301 if ((IS_CLASSREF(tinfo->typeclass)
2302 ? tinfo->typeclass.ref->name
2303 : tinfo->typeclass.cls->name) == declaredclassname)
2305 /* the class names are the same */
2306 /* equality is guaranteed by the loading constraints */
2310 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2311 stset->subtyperefs[0] = tinfo->typeclass;
2312 stset->subtyperefs[1].any = NULL; /* terminate */
2319 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2322 #endif /* ENABLE_VERIFIER */
2324 /* create_unresolved_class *****************************************************
2326 Create an unresolved_class struct for the given class reference
2329 refmethod........the method triggering the resolution (if any)
2330 classref.........the class reference
2331 valuetype........value type to check against the resolved class
2332 may be NULL, if no typeinfo is available
2335 a pointer to a new unresolved_class struct, or
2336 NULL if an exception has been thrown
2338 *******************************************************************************/
2340 #ifdef ENABLE_VERIFIER
2341 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2342 constant_classref *classref,
2343 typeinfo *valuetype)
2345 unresolved_class *ref;
2347 #ifdef RESOLVE_VERBOSE
2348 printf("create_unresolved_class\n");
2349 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2351 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2352 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2354 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2357 ref = NEW(unresolved_class);
2358 ref->classref = classref;
2359 ref->referermethod = refmethod;
2362 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2363 &(ref->subtypeconstraints),valuetype,classref->name))
2367 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2372 #endif /* ENABLE_VERIFIER */
2374 /* resolve_create_unresolved_field *********************************************
2376 Create an unresolved_field struct for the given field access instruction
2379 referer..........the class containing the reference
2380 refmethod........the method triggering the resolution (if any)
2381 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2384 a pointer to a new unresolved_field struct, or
2385 NULL if an exception has been thrown
2387 *******************************************************************************/
2389 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2390 methodinfo *refmethod,
2393 unresolved_field *ref;
2394 constant_FMIref *fieldref = NULL;
2396 #ifdef RESOLVE_VERBOSE
2397 printf("create_unresolved_field\n");
2398 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2399 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2400 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2403 ref = NEW(unresolved_field);
2405 ref->referermethod = refmethod;
2406 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2408 switch (iptr->opc) {
2410 ref->flags |= RESOLVE_PUTFIELD;
2413 case ICMD_PUTFIELDCONST:
2414 ref->flags |= RESOLVE_PUTFIELD;
2417 case ICMD_PUTSTATIC:
2418 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2421 case ICMD_PUTSTATICCONST:
2422 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2428 case ICMD_GETSTATIC:
2429 ref->flags |= RESOLVE_STATIC;
2432 #if !defined(NDEBUG)
2438 fieldref = iptr->sx.s23.s3.fmiref;
2442 #ifdef RESOLVE_VERBOSE
2443 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2444 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2445 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2446 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2450 ref->fieldref = fieldref;
2455 /* resolve_constrain_unresolved_field ******************************************
2457 Record subtype constraints for a field access.
2460 ref..............the unresolved_field structure of the access
2461 referer..........the class containing the reference
2462 refmethod........the method triggering the resolution (if any)
2463 instanceti.......instance typeinfo, if available
2464 valueti..........value typeinfo, if available
2467 true.............everything ok
2468 false............an exception has been thrown
2470 *******************************************************************************/
2472 #if defined(ENABLE_VERIFIER)
2473 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2475 methodinfo *refmethod,
2476 typeinfo *instanceti,
2479 constant_FMIref *fieldref;
2486 fieldref = ref->fieldref;
2489 #ifdef RESOLVE_VERBOSE
2490 printf("constrain_unresolved_field\n");
2491 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2492 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2493 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2494 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2495 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2496 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2497 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2501 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2502 fd = fieldref->parseddesc.fd;
2505 /* record subtype constraints for the instance type, if any */
2509 /* The instanceslot must contain a reference to a non-array type */
2510 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2511 exceptions_throw_verifyerror(refmethod,
2512 "illegal instruction: field access on non-reference");
2515 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2516 exceptions_throw_verifyerror(refmethod,
2517 "illegal instruction: field access on array");
2521 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2522 TYPEINFO_IS_NEWOBJECT(*instanceti))
2524 /* The instruction writes a field in an uninitialized object. */
2525 /* This is only allowed when a field of an uninitialized 'this' object is */
2526 /* written inside an initialization method */
2528 classinfo *initclass;
2529 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2532 exceptions_throw_verifyerror(refmethod,
2533 "accessing field of uninitialized object");
2536 /* XXX check that class of field == refmethod->class */
2537 initclass = refmethod->class; /* XXX classrefs */
2538 assert(initclass->state & CLASS_LOADED);
2539 assert(initclass->state & CLASS_LINKED);
2541 typeinfo_init_classinfo(&tinfo, initclass);
2545 insttip = instanceti;
2547 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2548 &(ref->instancetypes), insttip,
2549 FIELDREF_CLASSNAME(fieldref)))
2553 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2556 /* record subtype constraints for the value type, if any */
2558 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2560 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2561 &(ref->valueconstraints), valueti,
2562 fieldref->parseddesc.fd->classref->name))
2566 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2571 #endif /* ENABLE_VERIFIER */
2573 /* resolve_create_unresolved_method ********************************************
2575 Create an unresolved_method struct for the given method invocation
2578 referer..........the class containing the reference
2579 refmethod........the method triggering the resolution (if any)
2580 iptr.............the INVOKE* instruction
2583 a pointer to a new unresolved_method struct, or
2584 NULL if an exception has been thrown
2586 *******************************************************************************/
2588 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2589 methodinfo *refmethod,
2590 constant_FMIref *methodref,
2594 unresolved_method *ref;
2598 #ifdef RESOLVE_VERBOSE
2599 printf("create_unresolved_method\n");
2600 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2601 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2602 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2603 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2604 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2607 /* allocate params if necessary */
2608 if (!methodref->parseddesc.md->params)
2609 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2610 (invokestatic) ? ACC_STATIC : ACC_NONE))
2613 /* create the data structure */
2614 ref = NEW(unresolved_method);
2615 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2616 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2617 ref->referermethod = refmethod;
2618 ref->methodref = methodref;
2619 ref->paramconstraints = NULL;
2620 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2626 /* resolve_constrain_unresolved_method_instance ********************************
2628 Record subtype constraints for the instance argument of a method call.
2631 ref..............the unresolved_method structure of the call
2632 referer..........the class containing the reference
2633 refmethod........the method triggering the resolution (if any)
2634 iptr.............the INVOKE* instruction
2637 true.............everything ok
2638 false............an exception has been thrown
2640 *******************************************************************************/
2642 #if defined(ENABLE_VERIFIER)
2643 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2644 methodinfo *refmethod,
2645 typeinfo *instanceti,
2648 constant_FMIref *methodref;
2649 constant_classref *instanceref;
2654 methodref = ref->methodref;
2657 /* XXX clean this up */
2658 instanceref = IS_FMIREF_RESOLVED(methodref)
2659 ? class_get_self_classref(methodref->p.method->class)
2660 : methodref->p.classref;
2662 #ifdef RESOLVE_VERBOSE
2663 printf("resolve_constrain_unresolved_method_instance\n");
2664 printf(" rmethod: "); method_println(refmethod);
2665 printf(" mref : "); method_methodref_println(methodref);
2668 /* record subtype constraints for the instance type, if any */
2670 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2671 { /* XXX clean up */
2672 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2673 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2674 : CLASSREF_OR_CLASSINFO(refmethod->class);
2676 if (!typeinfo_init_class(tip, initclass))
2683 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2684 &(ref->instancetypes),tip,instanceref->name))
2689 #endif /* defined(ENABLE_VERIFIER) */
2692 /* resolve_constrain_unresolved_method_params *********************************
2694 Record subtype constraints for the non-instance arguments of a method call.
2697 jd...............current jitdata (for looking up variables)
2698 ref..............the unresolved_method structure of the call
2699 refmethod........the method triggering the resolution (if any)
2700 iptr.............the INVOKE* instruction
2703 true.............everything ok
2704 false............an exception has been thrown
2706 *******************************************************************************/
2708 #if defined(ENABLE_VERIFIER)
2709 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2710 unresolved_method *ref,
2711 methodinfo *refmethod,
2714 constant_FMIref *methodref;
2722 methodref = ref->methodref;
2724 md = methodref->parseddesc.md;
2726 assert(md->params != NULL);
2728 #ifdef RESOLVE_VERBOSE
2729 printf("resolve_constrain_unresolved_method_params\n");
2730 printf(" rmethod: "); method_println(refmethod);
2731 printf(" mref : "); method_methodref_println(methodref);
2734 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2736 /* record subtype constraints for the parameter types, if any */
2738 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2739 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2740 type = md->paramtypes[i+instancecount].type;
2743 assert(type == param->type);
2745 if (type == TYPE_ADR) {
2746 if (!ref->paramconstraints) {
2747 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2748 for (j=md->paramcount-1-instancecount; j>i; --j)
2749 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2751 assert(ref->paramconstraints);
2752 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2753 ref->paramconstraints + i,&(param->typeinfo),
2754 md->paramtypes[i+instancecount].classref->name))
2758 if (ref->paramconstraints)
2759 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2765 #endif /* ENABLE_VERIFIER */
2768 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2770 Record subtype constraints for the non-instance arguments of a method call.
2773 ref..............the unresolved_method structure of the call
2774 refmethod........the method triggering the resolution (if any)
2775 stack............TOS before the INVOKE instruction
2778 true.............everything ok
2779 false............an exception has been thrown
2781 *******************************************************************************/
2783 #if defined(ENABLE_VERIFIER)
2784 bool resolve_constrain_unresolved_method_params_stackbased(
2785 unresolved_method *ref,
2786 methodinfo *refmethod,
2787 typedescriptor *stack)
2789 constant_FMIref *methodref;
2790 typedescriptor *param;
2797 methodref = ref->methodref;
2799 md = methodref->parseddesc.md;
2801 assert(md->params != NULL);
2803 #ifdef RESOLVE_VERBOSE
2804 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2805 printf(" rmethod: "); method_println(refmethod);
2806 printf(" mref : "); method_methodref_println(methodref);
2809 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2811 /* record subtype constraints for the parameter types, if any */
2813 param = stack - (md->paramslots - 1 - instancecount);
2815 for (i = instancecount; i < md->paramcount; ++i) {
2816 type = md->paramtypes[i].type;
2818 assert(type == param->type);
2820 if (type == TYPE_ADR) {
2821 if (!ref->paramconstraints) {
2822 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2823 for (j = 0; j < i - instancecount; ++j)
2824 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2826 assert(ref->paramconstraints);
2827 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2828 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2829 md->paramtypes[i].classref->name))
2833 if (ref->paramconstraints)
2834 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2837 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2842 #endif /* ENABLE_VERIFIER */
2845 /******************************************************************************/
2846 /* FREEING MEMORY */
2847 /******************************************************************************/
2849 #ifdef ENABLE_VERIFIER
2850 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2853 classref_or_classinfo *p = list;
2855 /* this is silly. we *only* need to count the elements for MFREE */
2858 MFREE(list,classref_or_classinfo,(p - list));
2861 #endif /* ENABLE_VERIFIER */
2863 /* unresolved_class_free *******************************************************
2865 Free the memory used by an unresolved_class
2868 ref..............the unresolved_class
2870 *******************************************************************************/
2872 void unresolved_class_free(unresolved_class *ref)
2876 #ifdef ENABLE_VERIFIER
2877 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2879 FREE(ref,unresolved_class);
2882 /* unresolved_field_free *******************************************************
2884 Free the memory used by an unresolved_field
2887 ref..............the unresolved_field
2889 *******************************************************************************/
2891 void unresolved_field_free(unresolved_field *ref)
2895 #ifdef ENABLE_VERIFIER
2896 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2897 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2899 FREE(ref,unresolved_field);
2902 /* unresolved_method_free ******************************************************
2904 Free the memory used by an unresolved_method
2907 ref..............the unresolved_method
2909 *******************************************************************************/
2911 void unresolved_method_free(unresolved_method *ref)
2915 #ifdef ENABLE_VERIFIER
2916 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2917 if (ref->paramconstraints) {
2919 int count = ref->methodref->parseddesc.md->paramcount;
2921 for (i=0; i<count; ++i)
2922 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2923 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2926 FREE(ref,unresolved_method);
2929 /******************************************************************************/
2931 /******************************************************************************/
2933 #if !defined(NDEBUG)
2935 /* unresolved_subtype_set_debug_dump *******************************************
2937 Print debug info for unresolved_subtype_set to stream
2940 stset............the unresolved_subtype_set
2941 file.............the stream
2943 *******************************************************************************/
2945 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2947 classref_or_classinfo *p;
2949 if (SUBTYPESET_IS_EMPTY(*stset)) {
2950 fprintf(file," (empty)\n");
2953 p = stset->subtyperefs;
2954 for (;p->any; ++p) {
2955 if (IS_CLASSREF(*p)) {
2956 fprintf(file," ref: ");
2957 utf_fprint_printable_ascii(file,p->ref->name);
2960 fprintf(file," cls: ");
2961 utf_fprint_printable_ascii(file,p->cls->name);
2968 /* unresolved_class_debug_dump *************************************************
2970 Print debug info for unresolved_class to stream
2973 ref..............the unresolved_class
2974 file.............the stream
2976 *******************************************************************************/
2978 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2980 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2982 fprintf(file," referer : ");
2983 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2984 fprintf(file," refmethod : ");
2985 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2986 fprintf(file," refmethodd: ");
2987 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2988 fprintf(file," classname : ");
2989 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2990 fprintf(file," subtypeconstraints:\n");
2991 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2995 /* unresolved_field_debug_dump *************************************************
2997 Print debug info for unresolved_field to stream
3000 ref..............the unresolved_field
3001 file.............the stream
3003 *******************************************************************************/
3005 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3007 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3009 fprintf(file," referer : ");
3010 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3011 fprintf(file," refmethod : ");
3012 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3013 fprintf(file," refmethodd: ");
3014 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3015 fprintf(file," classname : ");
3016 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3017 fprintf(file," name : ");
3018 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3019 fprintf(file," descriptor: ");
3020 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3021 fprintf(file," parseddesc: ");
3022 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3023 fprintf(file," flags : %04x\n",ref->flags);
3024 fprintf(file," instancetypes:\n");
3025 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3026 fprintf(file," valueconstraints:\n");
3027 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3031 /* unresolved_method_debug_dump ************************************************
3033 Print debug info for unresolved_method to stream
3036 ref..............the unresolved_method
3037 file.............the stream
3039 *******************************************************************************/
3041 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3045 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3047 fprintf(file," referer : ");
3048 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3049 fprintf(file," refmethod : ");
3050 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3051 fprintf(file," refmethodd: ");
3052 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3053 fprintf(file," classname : ");
3054 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3055 fprintf(file," name : ");
3056 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3057 fprintf(file," descriptor: ");
3058 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3059 fprintf(file," parseddesc: ");
3060 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3061 fprintf(file," flags : %04x\n",ref->flags);
3062 fprintf(file," instancetypes:\n");
3063 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3064 fprintf(file," paramconstraints:\n");
3065 if (ref->paramconstraints) {
3066 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3067 fprintf(file," param %d:\n",i);
3068 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3072 fprintf(file," (empty)\n");
3076 #endif /* !defined(NDEBUG) */
3080 * These are local overrides for various environment variables in Emacs.
3081 * Please do not remove this and leave it at the end of the file, where
3082 * Emacs will automagically detect them.
3083 * ---------------------------------------------------------------------
3086 * indent-tabs-mode: t
3090 * vim:noexpandtab:sw=4:ts=4: