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
34 #include "mm/memory.h"
36 #include "vm/access.h"
37 #include "vm/exceptions.h"
38 #include "vm/global.h"
39 #include "vm/primitive.h"
40 #include "vm/resolve.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"
52 /******************************************************************************/
54 /******************************************************************************/
56 /*#define RESOLVE_VERBOSE*/
58 /******************************************************************************/
59 /* CLASS RESOLUTION */
60 /******************************************************************************/
62 /* resolve_class_from_name *****************************************************
64 Resolve a symbolic class reference
67 referer..........the class containing the reference
68 refmethod........the method from which resolution was triggered
69 (may be NULL if not applicable)
70 classname........class name to resolve
71 mode.............mode of resolution:
72 resolveLazy...only resolve if it does not
73 require loading classes
74 resolveEager..load classes if necessary
75 checkaccess......if true, access rights to the class are checked
76 link.............if true, guarantee that the returned class, if any,
80 *result..........set to result of resolution, or to NULL if
81 the reference has not been resolved
82 In the case of an exception, *result is
83 guaranteed to be set to NULL.
86 true.............everything ok
87 (*result may still be NULL for resolveLazy)
88 false............an exception has been thrown
91 The returned class is *not* guaranteed to be linked!
92 (It is guaranteed to be loaded, though.)
94 *******************************************************************************/
96 bool resolve_class_from_name(classinfo *referer,
97 methodinfo *refmethod,
114 assert(mode == resolveLazy || mode == resolveEager);
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);
126 /* lookup if this class has already been loaded */
128 cls = classcache_lookup(referer->classloader, classname);
130 #ifdef RESOLVE_VERBOSE
131 printf(" lookup result: %p\n",(void*)cls);
135 /* resolve array types */
137 if (classname->text[0] == '[') {
138 utf_ptr = classname->text + 1;
139 len = classname->blength - 1;
141 /* classname is an array type name */
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 */
156 assert(mode == resolveLazy);
157 return true; /* be lazy */
159 /* create the array class */
160 cls = class_array_of(cls,false);
162 return false; /* exception */
166 /* the class has not been loaded, yet */
167 if (mode == resolveLazy)
168 return true; /* be lazy */
171 #ifdef RESOLVE_VERBOSE
172 printf(" loading...\n");
178 cls = load_class_from_classloader(classname, referer->classloader);
181 /* If the exception is a ClassNotFoundException,
182 convert it to a NoClassDefFoundError. */
184 exceptions_classnotfoundexception_to_noclassdeffounderror();
191 /* the class is now loaded */
193 assert(cls->state & CLASS_LOADED);
195 #ifdef RESOLVE_VERBOSE
196 printf(" checking access rights...\n");
199 /* check access rights of referer to refered class */
201 if (checkaccess && !access_is_accessible_class(referer,cls)) {
203 utf_bytes(cls->name) +
204 utf_bytes(referer->name) +
207 msg = MNEW(char, msglen);
209 strcpy(msg, "class is not accessible (");
210 utf_cat_classname(msg, cls->name);
211 strcat(msg, " from ");
212 utf_cat_classname(msg, referer->name);
215 u = utf_new_char(msg);
217 MFREE(msg, char, msglen);
219 exceptions_throw_illegalaccessexception(u);
221 return false; /* exception */
224 /* link the class if necessary */
226 if (!(cls->state & CLASS_LINKED))
227 if (!link_class(cls))
228 return false; /* exception */
230 assert(cls->state & CLASS_LINKED);
233 /* resolution succeeds */
234 #ifdef RESOLVE_VERBOSE
235 printf(" success.\n");
241 /* resolve_classref ************************************************************
243 Resolve a symbolic class reference
246 refmethod........the method from which resolution was triggered
247 (may be NULL if not applicable)
248 ref..............class reference
249 mode.............mode of resolution:
250 resolveLazy...only resolve if it does not
251 require loading classes
252 resolveEager..load classes if necessary
253 checkaccess......if true, access rights to the class are checked
254 link.............if true, guarantee that the returned class, if any,
258 *result..........set to result of resolution, or to NULL if
259 the reference has not been resolved
260 In the case of an exception, *result is
261 guaranteed to be set to NULL.
264 true.............everything ok
265 (*result may still be NULL for resolveLazy)
266 false............an exception has been thrown
268 *******************************************************************************/
270 bool resolve_classref(methodinfo *refmethod,
271 constant_classref *ref,
277 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
280 /* resolve_classref_or_classinfo ***********************************************
282 Resolve a symbolic class reference if necessary
284 NOTE: If given, refmethod->class is used as the referring class.
285 Otherwise, cls.ref->referer is used.
288 refmethod........the method from which resolution was triggered
289 (may be NULL if not applicable)
290 cls..............class reference or classinfo
291 mode.............mode of resolution:
292 resolveLazy...only resolve if it does not
293 require loading classes
294 resolveEager..load classes if necessary
295 checkaccess......if true, access rights to the class are checked
296 link.............if true, guarantee that the returned class, if any,
300 *result..........set to result of resolution, or to NULL if
301 the reference has not been resolved
302 In the case of an exception, *result is
303 guaranteed to be set to NULL.
306 true.............everything ok
307 (*result may still be NULL for resolveLazy)
308 false............an exception has been thrown
310 *******************************************************************************/
312 bool resolve_classref_or_classinfo(methodinfo *refmethod,
313 classref_or_classinfo cls,
323 assert(mode == resolveEager || mode == resolveLazy);
326 #ifdef RESOLVE_VERBOSE
327 printf("resolve_classref_or_classinfo(");
328 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
329 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
334 if (IS_CLASSREF(cls)) {
335 /* we must resolve this reference */
337 /* determine which class to use as the referer */
339 /* Common cases are refmethod == NULL or both referring classes */
340 /* being the same, so the referer usually is cls.ref->referer. */
341 /* There is one important case where it is not: When we do a */
342 /* deferred assignability check to a formal argument of a method, */
343 /* we must use refmethod->class (the caller's class) to resolve */
344 /* the type of the formal argument. */
346 referer = (refmethod) ? refmethod->class : cls.ref->referer;
348 if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
349 mode, checkaccess, link, &c))
350 goto return_exception;
353 /* cls has already been resolved */
355 assert(c->state & CLASS_LOADED);
357 assert(c || (mode == resolveLazy));
360 return true; /* be lazy */
363 assert(c->state & CLASS_LOADED);
366 if (!(c->state & CLASS_LINKED))
368 goto return_exception;
370 assert(c->state & CLASS_LINKED);
383 /* resolve_classref_or_classinfo_eager *****************************************
385 Resolve a symbolic class reference eagerly if necessary.
386 No attempt is made to link the class.
389 cls..............class reference or classinfo
390 checkaccess......if true, access rights to the class are checked
393 classinfo *......the resolved class
394 NULL.............an exception has been thrown
396 *******************************************************************************/
398 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
403 if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
410 /* resolve_class_from_typedesc *************************************************
412 Return a classinfo * for the given type descriptor
415 d................type descriptor
416 checkaccess......if true, access rights to the class are checked
417 link.............if true, guarantee that the returned class, if any,
420 *result..........set to result of resolution, or to NULL if
421 the reference has not been resolved
422 In the case of an exception, *result is
423 guaranteed to be set to NULL.
426 true.............everything ok
427 false............an exception has been thrown
430 This function always resolves eagerly.
432 *******************************************************************************/
434 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
443 #ifdef RESOLVE_VERBOSE
444 printf("resolve_class_from_typedesc(");
445 descriptor_debug_print_typedesc(stdout,d);
446 printf(",%i,%i)\n",(int)checkaccess,(int)link);
449 if (d->type == TYPE_ADR) {
450 /* a reference type */
452 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
453 resolveEager,checkaccess,link,&cls))
454 return false; /* exception */
457 /* a primitive type */
459 cls = primitive_class_get_by_type(d->decltype);
461 assert(cls->state & CLASS_LOADED);
463 if (!(cls->state & CLASS_LINKED))
464 if (!link_class(cls))
465 return false; /* exception */
469 assert(cls->state & CLASS_LOADED);
470 assert(!link || (cls->state & CLASS_LINKED));
472 #ifdef RESOLVE_VERBOSE
473 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
480 /******************************************************************************/
481 /* SUBTYPE SET CHECKS */
482 /******************************************************************************/
484 /* resolve_subtype_check *******************************************************
486 Resolve the given types lazily and perform a subtype check
489 refmethod........the method triggering the resolution
490 subtype..........checked to be a subtype of supertype
491 supertype........the super type to check agaings
492 mode.............mode of resolution:
493 resolveLazy...only resolve if it does not
494 require loading classes
495 resolveEager..load classes if necessary
496 error............which type of exception to throw if
497 the test fails. May be:
498 resolveLinkageError, or
499 resolveIllegalAccessError
500 IMPORTANT: If error==resolveIllegalAccessError,
501 then array types are not checked.
504 resolveSucceeded.....the check succeeded
505 resolveDeferred......the check could not be performed due to
506 unresolved types. (This can only happen for
507 mode == resolveLazy.)
508 resolveFailed........the check failed, an exception has been thrown.
511 The types are resolved first, so any
512 exception which may occurr during resolution may
513 be thrown by this function.
515 *******************************************************************************/
517 #if defined(ENABLE_VERIFIER)
518 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
519 classref_or_classinfo subtype,
520 classref_or_classinfo supertype,
533 assert(supertype.any);
534 assert(mode == resolveLazy || mode == resolveEager);
535 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
537 /* resolve the subtype */
539 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
540 /* the subclass could not be resolved. therefore we are sure that */
541 /* no instances of this subclass will ever exist -> skip this test */
542 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
543 exceptions_clear_exception();
544 return resolveSucceeded;
547 return resolveDeferred; /* be lazy */
549 assert(subclass->state & CLASS_LINKED);
551 /* do not check access to protected members of arrays */
553 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
554 return resolveSucceeded;
557 /* perform the subtype check */
559 typeinfo_init_classinfo(&subti,subclass);
561 r = typeinfo_is_assignable_to_class(&subti,supertype);
562 if (r == typecheck_FAIL)
563 return resolveFailed; /* failed, exception is already set */
565 if (r == typecheck_MAYBE) {
566 assert(IS_CLASSREF(supertype));
567 if (mode == resolveEager) {
568 if (!resolve_classref_or_classinfo(refmethod,supertype,
569 resolveEager,false,true,
572 return resolveFailed;
574 assert(supertype.cls);
578 return resolveDeferred; /* be lazy */
582 /* sub class relationship is false */
584 #if defined(RESOLVE_VERBOSE)
585 printf("SUBTYPE CHECK FAILED!\n");
589 utf_bytes(subclass->name) +
590 utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
593 msg = MNEW(char, msglen);
595 strcpy(msg, (error == resolveIllegalAccessError) ?
596 "illegal access to protected member (" :
597 "subtype constraint violated (");
599 utf_cat_classname(msg, subclass->name);
600 strcat(msg, " is not a subclass of ");
601 utf_cat_classname(msg, CLASSREF_OR_CLASSINFO_NAME(supertype));
604 u = utf_new_char(msg);
606 if (error == resolveIllegalAccessError)
607 exceptions_throw_illegalaccessexception(u);
609 exceptions_throw_linkageerror(msg, NULL);
611 /* ATTENTION: We probably need msg for
612 exceptions_throw_linkageerror. */
614 MFREE(msg, char, msglen);
616 return resolveFailed; /* exception */
621 return resolveSucceeded;
623 #endif /* defined(ENABLE_VERIFIER) */
625 /* resolve_lazy_subtype_checks *************************************************
627 Resolve the types to check lazily and perform subtype checks
630 refmethod........the method triggering the resolution
631 subtinfo.........the typeinfo containing the subtypes
632 supertype........the supertype to test againgst
633 mode.............mode of resolution:
634 resolveLazy...only resolve if it does not
635 require loading classes
636 resolveEager..load classes if necessary
637 error............which type of exception to throw if
638 the test fails. May be:
639 resolveLinkageError, or
640 resolveIllegalAccessError
641 IMPORTANT: If error==resolveIllegalAccessError,
642 then array types in the set are skipped.
645 resolveSucceeded.....the check succeeded
646 resolveDeferred......the check could not be performed due to
648 resolveFailed........the check failed, an exception has been thrown.
651 The references in the set are resolved first, so any
652 exception which may occurr during resolution may
653 be thrown by this function.
655 *******************************************************************************/
657 #if defined(ENABLE_VERIFIER)
658 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
660 classref_or_classinfo supertype,
665 resolve_result_t result;
669 assert(supertype.any);
670 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
672 /* returnAddresses are illegal here */
674 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
675 exceptions_throw_verifyerror(refmethod,
676 "Invalid use of returnAddress");
677 return resolveFailed;
680 /* uninitialized objects are illegal here */
682 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
683 exceptions_throw_verifyerror(refmethod,
684 "Invalid use of uninitialized object");
685 return resolveFailed;
688 /* the nulltype is always assignable */
690 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
691 return resolveSucceeded;
693 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
695 if (supertype.cls == class_java_lang_Object
696 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
697 && refmethod->class->classloader == NULL))
699 return resolveSucceeded;
702 if (subtinfo->merged) {
704 /* for a merged type we have to do a series of checks */
706 count = subtinfo->merged->count;
707 for (i=0; i<count; ++i) {
708 classref_or_classinfo c = subtinfo->merged->list[i];
709 if (subtinfo->dimension > 0) {
710 /* a merge of array types */
711 /* the merged list contains the possible _element_ types, */
712 /* so we have to create array types with these elements. */
713 if (IS_CLASSREF(c)) {
714 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
717 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
721 /* do the subtype check against the type c */
723 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
724 if (result != resolveSucceeded)
730 /* a single type, this is the common case, hopefully */
732 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
733 == CLASSREF_OR_CLASSINFO_NAME(supertype))
735 /* the class names are the same */
736 /* equality is guaranteed by the loading constraints */
737 return resolveSucceeded;
741 /* some other type name, try to perform the check lazily */
743 return resolve_subtype_check(refmethod,
744 subtinfo->typeclass,supertype,
751 return resolveSucceeded;
753 #endif /* defined(ENABLE_VERIFIER) */
755 /* resolve_and_check_subtype_set ***********************************************
757 Resolve the references in the given set and test subtype relationships
760 refmethod........the method triggering the resolution
761 ref..............a set of class/interface references
763 typeref..........the type to test against the set
764 mode.............mode of resolution:
765 resolveLazy...only resolve if it does not
766 require loading classes
767 resolveEager..load classes if necessary
768 error............which type of exception to throw if
769 the test fails. May be:
770 resolveLinkageError, or
771 resolveIllegalAccessError
772 IMPORTANT: If error==resolveIllegalAccessError,
773 then array types in the set are skipped.
776 resolveSucceeded.....the check succeeded
777 resolveDeferred......the check could not be performed due to
778 unresolved types. (This can only happen if
779 mode == resolveLazy.)
780 resolveFailed........the check failed, an exception has been thrown.
783 The references in the set are resolved first, so any
784 exception which may occurr during resolution may
785 be thrown by this function.
787 *******************************************************************************/
789 #if defined(ENABLE_VERIFIER)
790 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
791 unresolved_subtype_set *ref,
792 classref_or_classinfo typeref,
796 classref_or_classinfo *setp;
797 typecheck_result checkresult;
802 assert(mode == resolveLazy || mode == resolveEager);
803 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
805 #if defined(RESOLVE_VERBOSE)
806 printf("resolve_and_check_subtype_set:\n");
807 unresolved_subtype_set_debug_dump(ref, stdout);
808 if (IS_CLASSREF(typeref))
809 class_classref_println(typeref.ref);
811 class_println(typeref.cls);
814 setp = ref->subtyperefs;
816 /* an empty set of tests always succeeds */
817 if (!setp || !setp->any) {
818 return resolveSucceeded;
821 /* first resolve the type if necessary */
822 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
823 return resolveFailed; /* exception */
825 return resolveDeferred; /* be lazy */
827 assert(typeref.cls->state & CLASS_LINKED);
829 /* iterate over the set members */
831 for (; setp->any; ++setp) {
832 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
833 #if defined(RESOLVE_VERBOSE)
834 if (checkresult != resolveSucceeded)
835 printf("SUBTYPE CHECK FAILED!\n");
837 if (checkresult != resolveSucceeded)
842 return resolveSucceeded;
844 #endif /* defined(ENABLE_VERIFIER) */
846 /******************************************************************************/
847 /* CLASS RESOLUTION */
848 /******************************************************************************/
850 /* resolve_class ***************************************************************
852 Resolve an unresolved class reference. The class is also linked.
855 ref..............struct containing the reference
856 mode.............mode of resolution:
857 resolveLazy...only resolve if it does not
858 require loading classes
859 resolveEager..load classes if necessary
860 checkaccess......if true, access rights to the class are checked
863 *result..........set to the result of resolution, or to NULL if
864 the reference has not been resolved
865 In the case of an exception, *result is
866 guaranteed to be set to NULL.
869 true.............everything ok
870 (*result may still be NULL for resolveLazy)
871 false............an exception has been thrown
873 *******************************************************************************/
875 #ifdef ENABLE_VERIFIER
876 bool resolve_class(unresolved_class *ref,
882 resolve_result_t checkresult;
886 assert(mode == resolveLazy || mode == resolveEager);
890 #ifdef RESOLVE_VERBOSE
891 unresolved_class_debug_dump(ref,stdout);
894 /* first we must resolve the class */
895 if (!resolve_classref(ref->referermethod,
896 ref->classref,mode,checkaccess,true,&cls))
898 /* the class reference could not be resolved */
899 return false; /* exception */
902 return true; /* be lazy */
905 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
907 /* now we check the subtype constraints */
909 checkresult = resolve_and_check_subtype_set(ref->referermethod,
910 &(ref->subtypeconstraints),
911 CLASSREF_OR_CLASSINFO(cls),
913 resolveLinkageError);
914 if (checkresult != resolveSucceeded)
915 return (bool) checkresult;
921 #endif /* ENABLE_VERIFIER */
923 /* resolve_classref_eager ******************************************************
925 Resolve an unresolved class reference eagerly. The class is also linked and
926 access rights to the class are checked.
929 ref..............constant_classref to the class
932 classinfo * to the class, or
933 NULL if an exception has been thrown
935 *******************************************************************************/
937 classinfo * resolve_classref_eager(constant_classref *ref)
941 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
947 /* resolve_classref_eager_nonabstract ******************************************
949 Resolve an unresolved class reference eagerly. The class is also linked and
950 access rights to the class are checked. A check is performed that the class
954 ref..............constant_classref to the class
957 classinfo * to the class, or
958 NULL if an exception has been thrown
960 *******************************************************************************/
962 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
966 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
969 /* ensure that the class is not abstract */
971 if (c->flags & ACC_ABSTRACT) {
972 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
979 /* resolve_class_eager *********************************************************
981 Resolve an unresolved class reference eagerly. The class is also linked and
982 access rights to the class are checked.
985 ref..............struct containing the reference
988 classinfo * to the class, or
989 NULL if an exception has been thrown
991 *******************************************************************************/
993 #ifdef ENABLE_VERIFIER
994 classinfo * resolve_class_eager(unresolved_class *ref)
998 if (!resolve_class(ref,resolveEager,true,&c))
1003 #endif /* ENABLE_VERIFIER */
1005 /* resolve_class_eager_no_access_check *****************************************
1007 Resolve an unresolved class reference eagerly. The class is also linked.
1008 Access rights are _not_ checked.
1011 ref..............struct containing the reference
1014 classinfo * to the class, or
1015 NULL if an exception has been thrown
1017 *******************************************************************************/
1019 #ifdef ENABLE_VERIFIER
1020 classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
1024 if (!resolve_class(ref, resolveEager, false, &c))
1029 #endif /* ENABLE_VERIFIER */
1031 /******************************************************************************/
1032 /* FIELD RESOLUTION */
1033 /******************************************************************************/
1035 /* resolve_field_verifier_checks *******************************************
1037 Do the verifier checks necessary after field has been resolved.
1040 refmethod........the method containing the reference
1041 fieldref.........the field reference
1042 container........the class where the field was found
1043 fi...............the fieldinfo of the resolved field
1044 instanceti.......instance typeinfo, if available
1045 valueti..........value typeinfo, if available
1046 isstatic.........true if this is a *STATIC* instruction
1047 isput............true if this is a PUT* instruction
1050 resolveSucceeded....everything ok
1051 resolveDeferred.....tests could not be done, have been deferred
1052 resolveFailed.......exception has been thrown
1054 *******************************************************************************/
1056 #if defined(ENABLE_VERIFIER)
1057 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
1058 constant_FMIref *fieldref,
1059 classinfo *container,
1061 typeinfo *instanceti,
1066 classinfo *declarer;
1068 resolve_result_t result;
1069 constant_classref *fieldtyperef;
1079 /* get the classinfos and the field type */
1081 referer = refmethod->class;
1084 declarer = fi->class;
1086 assert(referer->state & CLASS_LINKED);
1088 fieldtyperef = fieldref->parseddesc.fd->classref;
1093 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1096 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1097 /* a static field is accessed via an instance, or vice versa */
1098 exceptions_throw_incompatibleclasschangeerror(declarer,
1099 (fi->flags & ACC_STATIC)
1100 ? "static field accessed via instance"
1101 : "instance field accessed without instance");
1103 return resolveFailed;
1106 /* check access rights */
1108 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1110 utf_bytes(declarer->name) +
1111 utf_bytes(fi->name) +
1112 utf_bytes(referer->name) +
1115 msg = MNEW(char, msglen);
1117 strcpy(msg, "field is not accessible (");
1118 utf_cat_classname(msg, declarer->name);
1120 utf_cat(msg, fi->name);
1121 strcat(msg, " from ");
1122 utf_cat_classname(msg, referer->name);
1125 u = utf_new_char(msg);
1127 MFREE(msg, char, msglen);
1129 exceptions_throw_illegalaccessexception(u);
1131 return resolveFailed; /* exception */
1134 /* for non-static methods we have to check the constraints on the */
1141 /* The instanceslot must contain a reference to a non-array type */
1143 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1144 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1145 return resolveFailed;
1147 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1148 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1149 return resolveFailed;
1152 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1154 /* The instruction writes a field in an uninitialized object. */
1155 /* This is only allowed when a field of an uninitialized 'this' object is */
1156 /* written inside an initialization method */
1158 classinfo *initclass;
1159 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1162 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1163 return resolveFailed;
1166 /* XXX check that class of field == refmethod->class */
1167 initclass = referer; /* XXX classrefs */
1168 assert(initclass->state & CLASS_LINKED);
1170 typeinfo_init_classinfo(&tinfo, initclass);
1174 insttip = instanceti;
1177 result = resolve_lazy_subtype_checks(refmethod,
1179 CLASSREF_OR_CLASSINFO(container),
1180 resolveLinkageError);
1181 if (result != resolveSucceeded)
1184 /* check protected access */
1186 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1188 result = resolve_lazy_subtype_checks(refmethod,
1190 CLASSREF_OR_CLASSINFO(referer),
1191 resolveIllegalAccessError);
1192 if (result != resolveSucceeded)
1198 /* for PUT* instructions we have to check the constraints on the value type */
1201 assert(fieldtyperef);
1203 /* check subtype constraints */
1204 result = resolve_lazy_subtype_checks(refmethod,
1206 CLASSREF_OR_CLASSINFO(fieldtyperef),
1207 resolveLinkageError);
1209 if (result != resolveSucceeded)
1213 /* impose loading constraint on field type */
1215 if (fi->type == TYPE_ADR) {
1216 assert(fieldtyperef);
1217 if (!classcache_add_constraint(declarer->classloader,
1218 referer->classloader,
1219 fieldtyperef->name))
1220 return resolveFailed;
1223 /* XXX impose loading constraint on instance? */
1226 return resolveSucceeded;
1228 #endif /* defined(ENABLE_VERIFIER) */
1230 /* resolve_field_lazy **********************************************************
1232 Resolve an unresolved field reference lazily
1234 NOTE: This function does NOT do any verification checks. In case of a
1235 successful resolution, you must call resolve_field_verifier_checks
1236 in order to perform the necessary checks!
1239 refmethod........the referer method
1240 fieldref.........the field reference
1243 resolveSucceeded.....the reference has been resolved
1244 resolveDeferred......the resolving could not be performed lazily
1245 resolveFailed........resolving failed, an exception has been thrown.
1247 *******************************************************************************/
1249 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1250 constant_FMIref *fieldref)
1253 classinfo *container;
1258 /* the class containing the reference */
1260 referer = refmethod->class;
1263 /* check if the field itself is already resolved */
1265 if (IS_FMIREF_RESOLVED(fieldref))
1266 return resolveSucceeded;
1268 /* first we must resolve the class containg the field */
1270 /* XXX can/may lazyResolving trigger linking? */
1272 if (!resolve_class_from_name(referer, refmethod,
1273 fieldref->p.classref->name, resolveLazy, true, true, &container))
1275 /* the class reference could not be resolved */
1276 return resolveFailed; /* exception */
1279 return resolveDeferred; /* be lazy */
1281 assert(container->state & CLASS_LINKED);
1283 /* now we must find the declaration of the field in `container`
1284 * or one of its superclasses */
1286 fi = class_resolvefield(container,
1287 fieldref->name, fieldref->descriptor,
1290 /* The field does not exist. But since we were called lazily, */
1291 /* this error must not be reported now. (It will be reported */
1292 /* if eager resolving of this field is ever tried.) */
1294 exceptions_clear_exception();
1295 return resolveDeferred; /* be lazy */
1298 /* cache the result of the resolution */
1300 fieldref->p.field = fi;
1303 return resolveSucceeded;
1306 /* resolve_field ***************************************************************
1308 Resolve an unresolved field reference
1311 ref..............struct containing the reference
1312 mode.............mode of resolution:
1313 resolveLazy...only resolve if it does not
1314 require loading classes
1315 resolveEager..load classes if necessary
1318 *result..........set to the result of resolution, or to NULL if
1319 the reference has not been resolved
1320 In the case of an exception, *result is
1321 guaranteed to be set to NULL.
1324 true.............everything ok
1325 (*result may still be NULL for resolveLazy)
1326 false............an exception has been thrown
1328 *******************************************************************************/
1330 bool resolve_field(unresolved_field *ref,
1331 resolve_mode_t mode,
1335 classinfo *container;
1336 classinfo *declarer;
1337 constant_classref *fieldtyperef;
1339 resolve_result_t checkresult;
1343 assert(mode == resolveLazy || mode == resolveEager);
1347 #ifdef RESOLVE_VERBOSE
1348 unresolved_field_debug_dump(ref,stdout);
1351 /* the class containing the reference */
1353 referer = ref->referermethod->class;
1356 /* check if the field itself is already resolved */
1357 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1358 fi = ref->fieldref->p.field;
1359 container = fi->class;
1360 goto resolved_the_field;
1363 /* first we must resolve the class containg the field */
1364 if (!resolve_class_from_name(referer,ref->referermethod,
1365 ref->fieldref->p.classref->name,mode,true,true,&container))
1367 /* the class reference could not be resolved */
1368 return false; /* exception */
1371 return true; /* be lazy */
1374 assert(container->state & CLASS_LOADED);
1375 assert(container->state & CLASS_LINKED);
1377 /* now we must find the declaration of the field in `container`
1378 * or one of its superclasses */
1380 #ifdef RESOLVE_VERBOSE
1381 printf(" resolving field in class...\n");
1384 fi = class_resolvefield(container,
1385 ref->fieldref->name,ref->fieldref->descriptor,
1388 if (mode == resolveLazy) {
1389 /* The field does not exist. But since we were called lazily, */
1390 /* this error must not be reported now. (It will be reported */
1391 /* if eager resolving of this field is ever tried.) */
1393 exceptions_clear_exception();
1394 return true; /* be lazy */
1397 return false; /* exception */
1400 /* cache the result of the resolution */
1401 ref->fieldref->p.field = fi;
1405 #ifdef ENABLE_VERIFIER
1406 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1407 /* that no missing parts of an instruction will be accessed. */
1409 checkresult = resolve_field_verifier_checks(
1414 NULL, /* instanceti, handled by constraints below */
1415 NULL, /* valueti, handled by constraints below */
1416 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1417 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1419 if (checkresult != resolveSucceeded)
1420 return (bool) checkresult;
1422 declarer = fi->class;
1424 assert(declarer->state & CLASS_LOADED);
1425 assert(declarer->state & CLASS_LINKED);
1427 /* for non-static accesses we have to check the constraints on the */
1430 if (!(ref->flags & RESOLVE_STATIC)) {
1431 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1432 &(ref->instancetypes),
1433 CLASSREF_OR_CLASSINFO(container),
1434 mode, resolveLinkageError);
1435 if (checkresult != resolveSucceeded)
1436 return (bool) checkresult;
1439 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1441 /* for PUT* instructions we have to check the constraints on the value type */
1442 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1443 assert(fieldtyperef);
1444 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1445 /* check subtype constraints */
1446 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1447 &(ref->valueconstraints),
1448 CLASSREF_OR_CLASSINFO(fieldtyperef),
1449 mode, resolveLinkageError);
1450 if (checkresult != resolveSucceeded)
1451 return (bool) checkresult;
1455 /* check protected access */
1456 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1457 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1458 &(ref->instancetypes),
1459 CLASSREF_OR_CLASSINFO(referer),
1461 resolveIllegalAccessError);
1462 if (checkresult != resolveSucceeded)
1463 return (bool) checkresult;
1467 #endif /* ENABLE_VERIFIER */
1475 /* resolve_field_eager *********************************************************
1477 Resolve an unresolved field reference eagerly.
1480 ref..............struct containing the reference
1483 fieldinfo * to the field, or
1484 NULL if an exception has been thrown
1486 *******************************************************************************/
1488 fieldinfo * resolve_field_eager(unresolved_field *ref)
1492 if (!resolve_field(ref,resolveEager,&fi))
1498 /******************************************************************************/
1499 /* METHOD RESOLUTION */
1500 /******************************************************************************/
1502 /* resolve_method_invokespecial_lookup *****************************************
1504 Do the special lookup for methods invoked by INVOKESPECIAL
1507 refmethod........the method containing the reference
1508 mi...............the methodinfo of the resolved method
1511 a methodinfo *...the result of the lookup,
1512 NULL.............an exception has been thrown
1514 *******************************************************************************/
1516 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1519 classinfo *declarer;
1525 /* get referer and declarer classes */
1527 referer = refmethod->class;
1530 declarer = mi->class;
1532 assert(referer->state & CLASS_LINKED);
1534 /* checks for INVOKESPECIAL: */
1535 /* for <init> and methods of the current class we don't need any */
1536 /* special checks. Otherwise we must verify that the called method */
1537 /* belongs to a super class of the current class */
1539 if ((referer != declarer) && (mi->name != utf_init)) {
1540 /* check that declarer is a super class of the current class */
1542 if (!class_issubclass(referer,declarer)) {
1543 exceptions_throw_verifyerror(refmethod,
1544 "INVOKESPECIAL calling non-super class method");
1548 /* if the referer has ACC_SUPER set, we must do the special */
1549 /* lookup starting with the direct super class of referer */
1551 if ((referer->flags & ACC_SUPER) != 0) {
1552 mi = class_resolvemethod(referer->super.cls,
1557 /* the spec calls for an AbstractMethodError in this case */
1559 exceptions_throw_abstractmethoderror();
1570 /* resolve_method_verifier_checks ******************************************
1572 Do the verifier checks necessary after a method has been resolved.
1575 refmethod........the method containing the reference
1576 methodref........the method reference
1577 mi...............the methodinfo of the resolved method
1578 invokestatic.....true if the method is invoked by INVOKESTATIC
1581 resolveSucceeded....everything ok
1582 resolveDeferred.....tests could not be done, have been deferred
1583 resolveFailed.......exception has been thrown
1585 *******************************************************************************/
1587 #if defined(ENABLE_VERIFIER)
1588 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1589 constant_FMIref *methodref,
1593 classinfo *declarer;
1603 #ifdef RESOLVE_VERBOSE
1604 printf("resolve_method_verifier_checks\n");
1605 printf(" flags: %02x\n",mi->flags);
1608 /* get the classinfos and the method descriptor */
1610 referer = refmethod->class;
1613 declarer = mi->class;
1618 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1619 /* a static method is accessed via an instance, or vice versa */
1620 exceptions_throw_incompatibleclasschangeerror(declarer,
1621 (mi->flags & ACC_STATIC)
1622 ? "static method called via instance"
1623 : "instance method called without instance");
1625 return resolveFailed;
1628 /* check access rights */
1630 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1631 /* XXX clean this up. this should be in exceptions.c */
1634 utf_bytes(declarer->name) +
1635 utf_bytes(mi->name) +
1636 utf_bytes(mi->descriptor) +
1637 utf_bytes(referer->name) +
1640 msg = MNEW(char, msglen);
1642 strcpy(msg, "method is not accessible (");
1643 utf_cat_classname(msg, declarer->name);
1645 utf_cat(msg, mi->name);
1646 utf_cat(msg, mi->descriptor);
1647 strcat(msg, " from ");
1648 utf_cat_classname(msg, referer->name);
1651 u = utf_new_char(msg);
1653 MFREE(msg, char, msglen);
1655 exceptions_throw_illegalaccessexception(u);
1657 return resolveFailed; /* exception */
1662 return resolveSucceeded;
1664 #endif /* defined(ENABLE_VERIFIER) */
1667 /* resolve_method_instance_type_checks *****************************************
1669 Check the instance type of a method invocation.
1672 refmethod........the method containing the reference
1673 mi...............the methodinfo of the resolved method
1674 instanceti.......typeinfo of the instance slot
1675 invokespecial....true if the method is invoked by INVOKESPECIAL
1678 resolveSucceeded....everything ok
1679 resolveDeferred.....tests could not be done, have been deferred
1680 resolveFailed.......exception has been thrown
1682 *******************************************************************************/
1684 #if defined(ENABLE_VERIFIER)
1685 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1687 typeinfo *instanceti,
1692 resolve_result_t result;
1694 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1695 { /* XXX clean up */
1696 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1697 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1698 : CLASSREF_OR_CLASSINFO(refmethod->class);
1700 if (!typeinfo_init_class(tip, initclass))
1707 result = resolve_lazy_subtype_checks(refmethod,
1709 CLASSREF_OR_CLASSINFO(mi->class),
1710 resolveLinkageError);
1711 if (result != resolveSucceeded)
1714 /* check protected access */
1716 /* XXX use other `declarer` than mi->class? */
1717 if (((mi->flags & ACC_PROTECTED) != 0)
1718 && !SAME_PACKAGE(mi->class, refmethod->class))
1720 result = resolve_lazy_subtype_checks(refmethod,
1722 CLASSREF_OR_CLASSINFO(refmethod->class),
1723 resolveIllegalAccessError);
1724 if (result != resolveSucceeded)
1730 return resolveSucceeded;
1732 #endif /* defined(ENABLE_VERIFIER) */
1735 /* resolve_method_param_type_checks ********************************************
1737 Check non-instance parameter types of a method invocation.
1740 jd...............jitdata of the method doing the call
1741 refmethod........the method containing the reference
1742 iptr.............the invoke instruction
1743 mi...............the methodinfo of the resolved method
1744 invokestatic.....true if the method is invoked by INVOKESTATIC
1747 resolveSucceeded....everything ok
1748 resolveDeferred.....tests could not be done, have been deferred
1749 resolveFailed.......exception has been thrown
1751 *******************************************************************************/
1753 #if defined(ENABLE_VERIFIER)
1754 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1755 methodinfo *refmethod,
1761 resolve_result_t result;
1763 typedesc *paramtypes;
1770 instancecount = (invokestatic) ? 0 : 1;
1772 /* check subtype constraints for TYPE_ADR parameters */
1774 md = mi->parseddesc;
1775 paramtypes = md->paramtypes;
1777 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1778 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1779 type = md->paramtypes[i+instancecount].type;
1782 assert(type == param->type);
1784 if (type == TYPE_ADR) {
1785 result = resolve_lazy_subtype_checks(refmethod,
1787 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1788 resolveLinkageError);
1789 if (result != resolveSucceeded)
1796 return resolveSucceeded;
1798 #endif /* defined(ENABLE_VERIFIER) */
1801 /* resolve_method_param_type_checks_stackbased *********************************
1803 Check non-instance parameter types of a method invocation.
1806 refmethod........the method containing the reference
1807 mi...............the methodinfo of the resolved method
1808 invokestatic.....true if the method is invoked by INVOKESTATIC
1809 stack............TOS before the INVOKE instruction
1812 resolveSucceeded....everything ok
1813 resolveDeferred.....tests could not be done, have been deferred
1814 resolveFailed.......exception has been thrown
1816 *******************************************************************************/
1818 #if defined(ENABLE_VERIFIER)
1819 resolve_result_t resolve_method_param_type_checks_stackbased(
1820 methodinfo *refmethod,
1823 typedescriptor *stack)
1825 typedescriptor *param;
1826 resolve_result_t result;
1828 typedesc *paramtypes;
1833 instancecount = (invokestatic) ? 0 : 1;
1835 /* check subtype constraints for TYPE_ADR parameters */
1837 md = mi->parseddesc;
1838 paramtypes = md->paramtypes;
1840 param = stack - (md->paramslots - 1 - instancecount);
1842 for (i = instancecount; i < md->paramcount; ++i) {
1843 type = md->paramtypes[i].type;
1845 assert(type == param->type);
1847 if (type == TYPE_ADR) {
1848 result = resolve_lazy_subtype_checks(refmethod,
1850 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1851 resolveLinkageError);
1852 if (result != resolveSucceeded)
1856 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1861 return resolveSucceeded;
1863 #endif /* defined(ENABLE_VERIFIER) */
1866 /* resolve_method_loading_constraints ******************************************
1868 Impose loading constraints on the parameters and return type of the
1872 referer..........the class refering to the method
1873 mi...............the method
1876 true................everything ok
1877 false...............an exception has been thrown
1879 *******************************************************************************/
1881 #if defined(ENABLE_VERIFIER)
1882 bool resolve_method_loading_constraints(classinfo *referer,
1886 typedesc *paramtypes;
1891 /* impose loading constraints on parameters (including instance) */
1893 md = mi->parseddesc;
1894 paramtypes = md->paramtypes;
1895 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1897 for (i = 0; i < md->paramcount; i++) {
1898 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1899 if (i < instancecount) {
1900 /* The type of the 'this' pointer is the class containing */
1901 /* the method definition. Since container is the same as, */
1902 /* or a subclass of declarer, we also constrain declarer */
1903 /* by transitivity of loading constraints. */
1904 name = mi->class->name;
1907 name = paramtypes[i].classref->name;
1910 /* The caller (referer) and the callee (container) must agree */
1911 /* on the types of the parameters. */
1912 if (!classcache_add_constraint(referer->classloader,
1913 mi->class->classloader, name))
1914 return false; /* exception */
1918 /* impose loading constraint onto return type */
1920 if (md->returntype.type == TYPE_ADR) {
1921 /* The caller (referer) and the callee (container) must agree */
1922 /* on the return type. */
1923 if (!classcache_add_constraint(referer->classloader,
1924 mi->class->classloader,
1925 md->returntype.classref->name))
1926 return false; /* exception */
1933 #endif /* defined(ENABLE_VERIFIER) */
1936 /* resolve_method_lazy *********************************************************
1938 Resolve an unresolved method reference lazily
1940 NOTE: This function does NOT do any verification checks. In case of a
1941 successful resolution, you must call resolve_method_verifier_checks
1942 in order to perform the necessary checks!
1945 refmethod........the referer method
1946 methodref........the method reference
1947 invokespecial....true if this is an INVOKESPECIAL instruction
1950 resolveSucceeded.....the reference has been resolved
1951 resolveDeferred......the resolving could not be performed lazily
1952 resolveFailed........resolving failed, an exception has been thrown.
1954 *******************************************************************************/
1956 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1957 constant_FMIref *methodref,
1961 classinfo *container;
1966 #ifdef RESOLVE_VERBOSE
1967 printf("resolve_method_lazy\n");
1970 /* the class containing the reference */
1972 referer = refmethod->class;
1975 /* check if the method itself is already resolved */
1977 if (IS_FMIREF_RESOLVED(methodref))
1978 return resolveSucceeded;
1980 /* first we must resolve the class containg the method */
1982 if (!resolve_class_from_name(referer, refmethod,
1983 methodref->p.classref->name, resolveLazy, true, true, &container))
1985 /* the class reference could not be resolved */
1986 return resolveFailed; /* exception */
1989 return resolveDeferred; /* be lazy */
1991 assert(container->state & CLASS_LINKED);
1993 /* now we must find the declaration of the method in `container`
1994 * or one of its superclasses */
1996 if (container->flags & ACC_INTERFACE) {
1997 mi = class_resolveinterfacemethod(container,
1999 methodref->descriptor,
2003 mi = class_resolveclassmethod(container,
2005 methodref->descriptor,
2010 /* The method does not exist. But since we were called lazily, */
2011 /* this error must not be reported now. (It will be reported */
2012 /* if eager resolving of this method is ever tried.) */
2014 exceptions_clear_exception();
2015 return resolveDeferred; /* be lazy */
2018 if (invokespecial) {
2019 mi = resolve_method_invokespecial_lookup(refmethod, mi);
2021 return resolveFailed; /* exception */
2024 /* have the method params already been parsed? no, do it. */
2026 if (!mi->parseddesc->params)
2027 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2028 return resolveFailed;
2030 /* cache the result of the resolution */
2032 methodref->p.method = mi;
2036 return resolveSucceeded;
2039 /* resolve_method **************************************************************
2041 Resolve an unresolved method reference
2044 ref..............struct containing the reference
2045 mode.............mode of resolution:
2046 resolveLazy...only resolve if it does not
2047 require loading classes
2048 resolveEager..load classes if necessary
2051 *result..........set to the result of resolution, or to NULL if
2052 the reference has not been resolved
2053 In the case of an exception, *result is
2054 guaranteed to be set to NULL.
2057 true.............everything ok
2058 (*result may still be NULL for resolveLazy)
2059 false............an exception has been thrown
2061 *******************************************************************************/
2063 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2066 classinfo *container;
2067 classinfo *declarer;
2069 typedesc *paramtypes;
2072 resolve_result_t checkresult;
2076 assert(mode == resolveLazy || mode == resolveEager);
2078 #ifdef RESOLVE_VERBOSE
2079 unresolved_method_debug_dump(ref,stdout);
2084 /* the class containing the reference */
2086 referer = ref->referermethod->class;
2089 /* check if the method itself is already resolved */
2091 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2092 mi = ref->methodref->p.method;
2093 container = mi->class;
2094 goto resolved_the_method;
2097 /* first we must resolve the class containing the method */
2099 if (!resolve_class_from_name(referer,ref->referermethod,
2100 ref->methodref->p.classref->name,mode,true,true,&container))
2102 /* the class reference could not be resolved */
2103 return false; /* exception */
2106 return true; /* be lazy */
2109 assert(container->state & CLASS_LINKED);
2111 /* now we must find the declaration of the method in `container`
2112 * or one of its superclasses */
2114 if (container->flags & ACC_INTERFACE) {
2115 mi = class_resolveinterfacemethod(container,
2116 ref->methodref->name,
2117 ref->methodref->descriptor,
2121 mi = class_resolveclassmethod(container,
2122 ref->methodref->name,
2123 ref->methodref->descriptor,
2128 if (mode == resolveLazy) {
2129 /* The method does not exist. But since we were called lazily, */
2130 /* this error must not be reported now. (It will be reported */
2131 /* if eager resolving of this method is ever tried.) */
2133 exceptions_clear_exception();
2134 return true; /* be lazy */
2137 return false; /* exception */ /* XXX set exceptionptr? */
2140 /* { the method reference has been resolved } */
2142 if (ref->flags & RESOLVE_SPECIAL) {
2143 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2145 return false; /* exception */
2148 /* have the method params already been parsed? no, do it. */
2150 if (!mi->parseddesc->params)
2151 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2154 /* cache the resolution */
2156 ref->methodref->p.method = mi;
2158 resolved_the_method:
2160 #ifdef ENABLE_VERIFIER
2163 checkresult = resolve_method_verifier_checks(
2167 (ref->flags & RESOLVE_STATIC));
2169 if (checkresult != resolveSucceeded)
2170 return (bool) checkresult;
2172 /* impose loading constraints on params and return type */
2174 if (!resolve_method_loading_constraints(referer, mi))
2177 declarer = mi->class;
2179 assert(referer->state & CLASS_LINKED);
2181 /* for non-static methods we have to check the constraints on the */
2184 if (!(ref->flags & RESOLVE_STATIC)) {
2185 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2186 &(ref->instancetypes),
2187 CLASSREF_OR_CLASSINFO(container),
2189 resolveLinkageError);
2190 if (checkresult != resolveSucceeded)
2191 return (bool) checkresult;
2198 /* check subtype constraints for TYPE_ADR parameters */
2200 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2201 paramtypes = mi->parseddesc->paramtypes;
2203 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2204 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2205 if (ref->paramconstraints) {
2206 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2207 ref->paramconstraints + i,
2208 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2210 resolveLinkageError);
2211 if (checkresult != resolveSucceeded)
2212 return (bool) checkresult;
2217 /* check protected access */
2219 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2221 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2222 &(ref->instancetypes),
2223 CLASSREF_OR_CLASSINFO(referer),
2225 resolveIllegalAccessError);
2226 if (checkresult != resolveSucceeded)
2227 return (bool) checkresult;
2230 #endif /* ENABLE_VERIFIER */
2237 /* resolve_method_eager ********************************************************
2239 Resolve an unresolved method reference eagerly.
2242 ref..............struct containing the reference
2245 methodinfo * to the method, or
2246 NULL if an exception has been thrown
2248 *******************************************************************************/
2250 methodinfo * resolve_method_eager(unresolved_method *ref)
2254 if (!resolve_method(ref,resolveEager,&mi))
2260 /******************************************************************************/
2261 /* CREATING THE DATA STRUCTURES */
2262 /******************************************************************************/
2264 #ifdef ENABLE_VERIFIER
2265 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2266 methodinfo *refmethod,
2267 unresolved_subtype_set *stset,
2269 utf *declaredclassname)
2277 #ifdef RESOLVE_VERBOSE
2278 printf("unresolved_subtype_set_from_typeinfo\n");
2279 #ifdef TYPEINFO_DEBUG
2280 typeinfo_print(stdout,tinfo,4);
2282 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2286 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2287 exceptions_throw_verifyerror(refmethod,
2288 "Invalid use of returnAddress");
2292 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2293 exceptions_throw_verifyerror(refmethod,
2294 "Invalid use of uninitialized object");
2298 /* the nulltype is always assignable */
2299 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2302 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2303 if (declaredclassname == utf_java_lang_Object
2304 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2309 if (tinfo->merged) {
2310 count = tinfo->merged->count;
2311 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2312 for (i=0; i<count; ++i) {
2313 classref_or_classinfo c = tinfo->merged->list[i];
2314 if (tinfo->dimension > 0) {
2315 /* a merge of array types */
2316 /* the merged list contains the possible _element_ types, */
2317 /* so we have to create array types with these elements. */
2318 if (IS_CLASSREF(c)) {
2319 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2322 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2325 stset->subtyperefs[i] = c;
2327 stset->subtyperefs[count].any = NULL; /* terminate */
2330 if ((IS_CLASSREF(tinfo->typeclass)
2331 ? tinfo->typeclass.ref->name
2332 : tinfo->typeclass.cls->name) == declaredclassname)
2334 /* the class names are the same */
2335 /* equality is guaranteed by the loading constraints */
2339 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2340 stset->subtyperefs[0] = tinfo->typeclass;
2341 stset->subtyperefs[1].any = NULL; /* terminate */
2348 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2351 #endif /* ENABLE_VERIFIER */
2353 /* create_unresolved_class *****************************************************
2355 Create an unresolved_class struct for the given class reference
2358 refmethod........the method triggering the resolution (if any)
2359 classref.........the class reference
2360 valuetype........value type to check against the resolved class
2361 may be NULL, if no typeinfo is available
2364 a pointer to a new unresolved_class struct, or
2365 NULL if an exception has been thrown
2367 *******************************************************************************/
2369 #ifdef ENABLE_VERIFIER
2370 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2371 constant_classref *classref,
2372 typeinfo *valuetype)
2374 unresolved_class *ref;
2376 #ifdef RESOLVE_VERBOSE
2377 printf("create_unresolved_class\n");
2378 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2380 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2381 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2383 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2386 ref = NEW(unresolved_class);
2387 ref->classref = classref;
2388 ref->referermethod = refmethod;
2391 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2392 &(ref->subtypeconstraints),valuetype,classref->name))
2396 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2401 #endif /* ENABLE_VERIFIER */
2403 /* resolve_create_unresolved_field *********************************************
2405 Create an unresolved_field struct for the given field access instruction
2408 referer..........the class containing the reference
2409 refmethod........the method triggering the resolution (if any)
2410 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2413 a pointer to a new unresolved_field struct, or
2414 NULL if an exception has been thrown
2416 *******************************************************************************/
2418 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2419 methodinfo *refmethod,
2422 unresolved_field *ref;
2423 constant_FMIref *fieldref = NULL;
2425 #ifdef RESOLVE_VERBOSE
2426 printf("create_unresolved_field\n");
2427 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2428 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2429 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2432 ref = NEW(unresolved_field);
2434 ref->referermethod = refmethod;
2435 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2437 switch (iptr->opc) {
2439 ref->flags |= RESOLVE_PUTFIELD;
2442 case ICMD_PUTFIELDCONST:
2443 ref->flags |= RESOLVE_PUTFIELD;
2446 case ICMD_PUTSTATIC:
2447 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2450 case ICMD_PUTSTATICCONST:
2451 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2457 case ICMD_GETSTATIC:
2458 ref->flags |= RESOLVE_STATIC;
2461 #if !defined(NDEBUG)
2467 fieldref = iptr->sx.s23.s3.fmiref;
2471 #ifdef RESOLVE_VERBOSE
2472 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2473 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2474 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2475 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2479 ref->fieldref = fieldref;
2484 /* resolve_constrain_unresolved_field ******************************************
2486 Record subtype constraints for a field access.
2489 ref..............the unresolved_field structure of the access
2490 referer..........the class containing the reference
2491 refmethod........the method triggering the resolution (if any)
2492 instanceti.......instance typeinfo, if available
2493 valueti..........value typeinfo, if available
2496 true.............everything ok
2497 false............an exception has been thrown
2499 *******************************************************************************/
2501 #if defined(ENABLE_VERIFIER)
2502 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2504 methodinfo *refmethod,
2505 typeinfo *instanceti,
2508 constant_FMIref *fieldref;
2515 fieldref = ref->fieldref;
2518 #ifdef RESOLVE_VERBOSE
2519 printf("constrain_unresolved_field\n");
2520 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2521 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2522 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2523 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2524 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2525 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2526 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2530 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2531 fd = fieldref->parseddesc.fd;
2534 /* record subtype constraints for the instance type, if any */
2538 /* The instanceslot must contain a reference to a non-array type */
2539 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2540 exceptions_throw_verifyerror(refmethod,
2541 "illegal instruction: field access on non-reference");
2544 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2545 exceptions_throw_verifyerror(refmethod,
2546 "illegal instruction: field access on array");
2550 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2551 TYPEINFO_IS_NEWOBJECT(*instanceti))
2553 /* The instruction writes a field in an uninitialized object. */
2554 /* This is only allowed when a field of an uninitialized 'this' object is */
2555 /* written inside an initialization method */
2557 classinfo *initclass;
2558 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2561 exceptions_throw_verifyerror(refmethod,
2562 "accessing field of uninitialized object");
2565 /* XXX check that class of field == refmethod->class */
2566 initclass = refmethod->class; /* XXX classrefs */
2567 assert(initclass->state & CLASS_LOADED);
2568 assert(initclass->state & CLASS_LINKED);
2570 typeinfo_init_classinfo(&tinfo, initclass);
2574 insttip = instanceti;
2576 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2577 &(ref->instancetypes), insttip,
2578 FIELDREF_CLASSNAME(fieldref)))
2582 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2585 /* record subtype constraints for the value type, if any */
2587 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2589 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2590 &(ref->valueconstraints), valueti,
2591 fieldref->parseddesc.fd->classref->name))
2595 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2600 #endif /* ENABLE_VERIFIER */
2602 /* resolve_create_unresolved_method ********************************************
2604 Create an unresolved_method struct for the given method invocation
2607 referer..........the class containing the reference
2608 refmethod........the method triggering the resolution (if any)
2609 iptr.............the INVOKE* instruction
2612 a pointer to a new unresolved_method struct, or
2613 NULL if an exception has been thrown
2615 *******************************************************************************/
2617 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2618 methodinfo *refmethod,
2619 constant_FMIref *methodref,
2623 unresolved_method *ref;
2627 #ifdef RESOLVE_VERBOSE
2628 printf("create_unresolved_method\n");
2629 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2630 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2631 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2632 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2633 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2636 /* allocate params if necessary */
2637 if (!methodref->parseddesc.md->params)
2638 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2639 (invokestatic) ? ACC_STATIC : ACC_NONE))
2642 /* create the data structure */
2643 ref = NEW(unresolved_method);
2644 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2645 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2646 ref->referermethod = refmethod;
2647 ref->methodref = methodref;
2648 ref->paramconstraints = NULL;
2649 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2655 /* resolve_constrain_unresolved_method_instance ********************************
2657 Record subtype constraints for the instance argument of a method call.
2660 ref..............the unresolved_method structure of the call
2661 referer..........the class containing the reference
2662 refmethod........the method triggering the resolution (if any)
2663 iptr.............the INVOKE* instruction
2666 true.............everything ok
2667 false............an exception has been thrown
2669 *******************************************************************************/
2671 #if defined(ENABLE_VERIFIER)
2672 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2673 methodinfo *refmethod,
2674 typeinfo *instanceti,
2677 constant_FMIref *methodref;
2678 constant_classref *instanceref;
2683 methodref = ref->methodref;
2686 /* XXX clean this up */
2687 instanceref = IS_FMIREF_RESOLVED(methodref)
2688 ? class_get_self_classref(methodref->p.method->class)
2689 : methodref->p.classref;
2691 #ifdef RESOLVE_VERBOSE
2692 printf("resolve_constrain_unresolved_method_instance\n");
2693 printf(" rmethod: "); method_println(refmethod);
2694 printf(" mref : "); method_methodref_println(methodref);
2697 /* record subtype constraints for the instance type, if any */
2699 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2700 { /* XXX clean up */
2701 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2702 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2703 : CLASSREF_OR_CLASSINFO(refmethod->class);
2705 if (!typeinfo_init_class(tip, initclass))
2712 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2713 &(ref->instancetypes),tip,instanceref->name))
2718 #endif /* defined(ENABLE_VERIFIER) */
2721 /* resolve_constrain_unresolved_method_params *********************************
2723 Record subtype constraints for the non-instance arguments of a method call.
2726 jd...............current jitdata (for looking up variables)
2727 ref..............the unresolved_method structure of the call
2728 refmethod........the method triggering the resolution (if any)
2729 iptr.............the INVOKE* instruction
2732 true.............everything ok
2733 false............an exception has been thrown
2735 *******************************************************************************/
2737 #if defined(ENABLE_VERIFIER)
2738 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2739 unresolved_method *ref,
2740 methodinfo *refmethod,
2743 constant_FMIref *methodref;
2751 methodref = ref->methodref;
2753 md = methodref->parseddesc.md;
2755 assert(md->params != NULL);
2757 #ifdef RESOLVE_VERBOSE
2758 printf("resolve_constrain_unresolved_method_params\n");
2759 printf(" rmethod: "); method_println(refmethod);
2760 printf(" mref : "); method_methodref_println(methodref);
2763 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2765 /* record subtype constraints for the parameter types, if any */
2767 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2768 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2769 type = md->paramtypes[i+instancecount].type;
2772 assert(type == param->type);
2774 if (type == TYPE_ADR) {
2775 if (!ref->paramconstraints) {
2776 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2777 for (j=md->paramcount-1-instancecount; j>i; --j)
2778 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2780 assert(ref->paramconstraints);
2781 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2782 ref->paramconstraints + i,&(param->typeinfo),
2783 md->paramtypes[i+instancecount].classref->name))
2787 if (ref->paramconstraints)
2788 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2794 #endif /* ENABLE_VERIFIER */
2797 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2799 Record subtype constraints for the non-instance arguments of a method call.
2802 ref..............the unresolved_method structure of the call
2803 refmethod........the method triggering the resolution (if any)
2804 stack............TOS before the INVOKE instruction
2807 true.............everything ok
2808 false............an exception has been thrown
2810 *******************************************************************************/
2812 #if defined(ENABLE_VERIFIER)
2813 bool resolve_constrain_unresolved_method_params_stackbased(
2814 unresolved_method *ref,
2815 methodinfo *refmethod,
2816 typedescriptor *stack)
2818 constant_FMIref *methodref;
2819 typedescriptor *param;
2826 methodref = ref->methodref;
2828 md = methodref->parseddesc.md;
2830 assert(md->params != NULL);
2832 #ifdef RESOLVE_VERBOSE
2833 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2834 printf(" rmethod: "); method_println(refmethod);
2835 printf(" mref : "); method_methodref_println(methodref);
2838 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2840 /* record subtype constraints for the parameter types, if any */
2842 param = stack - (md->paramslots - 1 - instancecount);
2844 for (i = instancecount; i < md->paramcount; ++i) {
2845 type = md->paramtypes[i].type;
2847 assert(type == param->type);
2849 if (type == TYPE_ADR) {
2850 if (!ref->paramconstraints) {
2851 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2852 for (j = 0; j < i - instancecount; ++j)
2853 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2855 assert(ref->paramconstraints);
2856 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2857 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2858 md->paramtypes[i].classref->name))
2862 if (ref->paramconstraints)
2863 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2866 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2871 #endif /* ENABLE_VERIFIER */
2874 /******************************************************************************/
2875 /* FREEING MEMORY */
2876 /******************************************************************************/
2878 #ifdef ENABLE_VERIFIER
2879 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2882 classref_or_classinfo *p = list;
2884 /* this is silly. we *only* need to count the elements for MFREE */
2887 MFREE(list,classref_or_classinfo,(p - list));
2890 #endif /* ENABLE_VERIFIER */
2892 /* unresolved_class_free *******************************************************
2894 Free the memory used by an unresolved_class
2897 ref..............the unresolved_class
2899 *******************************************************************************/
2901 void unresolved_class_free(unresolved_class *ref)
2905 #ifdef ENABLE_VERIFIER
2906 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2908 FREE(ref,unresolved_class);
2911 /* unresolved_field_free *******************************************************
2913 Free the memory used by an unresolved_field
2916 ref..............the unresolved_field
2918 *******************************************************************************/
2920 void unresolved_field_free(unresolved_field *ref)
2924 #ifdef ENABLE_VERIFIER
2925 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2926 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2928 FREE(ref,unresolved_field);
2931 /* unresolved_method_free ******************************************************
2933 Free the memory used by an unresolved_method
2936 ref..............the unresolved_method
2938 *******************************************************************************/
2940 void unresolved_method_free(unresolved_method *ref)
2944 #ifdef ENABLE_VERIFIER
2945 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2946 if (ref->paramconstraints) {
2948 int count = ref->methodref->parseddesc.md->paramcount;
2950 for (i=0; i<count; ++i)
2951 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2952 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2955 FREE(ref,unresolved_method);
2958 /******************************************************************************/
2960 /******************************************************************************/
2962 #if !defined(NDEBUG)
2964 /* unresolved_subtype_set_debug_dump *******************************************
2966 Print debug info for unresolved_subtype_set to stream
2969 stset............the unresolved_subtype_set
2970 file.............the stream
2972 *******************************************************************************/
2974 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2976 classref_or_classinfo *p;
2978 if (SUBTYPESET_IS_EMPTY(*stset)) {
2979 fprintf(file," (empty)\n");
2982 p = stset->subtyperefs;
2983 for (;p->any; ++p) {
2984 if (IS_CLASSREF(*p)) {
2985 fprintf(file," ref: ");
2986 utf_fprint_printable_ascii(file,p->ref->name);
2989 fprintf(file," cls: ");
2990 utf_fprint_printable_ascii(file,p->cls->name);
2997 /* unresolved_class_debug_dump *************************************************
2999 Print debug info for unresolved_class to stream
3002 ref..............the unresolved_class
3003 file.............the stream
3005 *******************************************************************************/
3007 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3009 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3011 fprintf(file," referer : ");
3012 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3013 fprintf(file," refmethod : ");
3014 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3015 fprintf(file," refmethodd: ");
3016 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3017 fprintf(file," classname : ");
3018 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3019 fprintf(file," subtypeconstraints:\n");
3020 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3024 /* unresolved_field_debug_dump *************************************************
3026 Print debug info for unresolved_field to stream
3029 ref..............the unresolved_field
3030 file.............the stream
3032 *******************************************************************************/
3034 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3036 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3038 fprintf(file," referer : ");
3039 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3040 fprintf(file," refmethod : ");
3041 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3042 fprintf(file," refmethodd: ");
3043 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3044 fprintf(file," classname : ");
3045 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3046 fprintf(file," name : ");
3047 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3048 fprintf(file," descriptor: ");
3049 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3050 fprintf(file," parseddesc: ");
3051 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3052 fprintf(file," flags : %04x\n",ref->flags);
3053 fprintf(file," instancetypes:\n");
3054 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3055 fprintf(file," valueconstraints:\n");
3056 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3060 /* unresolved_method_debug_dump ************************************************
3062 Print debug info for unresolved_method to stream
3065 ref..............the unresolved_method
3066 file.............the stream
3068 *******************************************************************************/
3070 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3074 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3076 fprintf(file," referer : ");
3077 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3078 fprintf(file," refmethod : ");
3079 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3080 fprintf(file," refmethodd: ");
3081 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3082 fprintf(file," classname : ");
3083 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3084 fprintf(file," name : ");
3085 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3086 fprintf(file," descriptor: ");
3087 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3088 fprintf(file," parseddesc: ");
3089 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3090 fprintf(file," flags : %04x\n",ref->flags);
3091 fprintf(file," instancetypes:\n");
3092 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3093 fprintf(file," paramconstraints:\n");
3094 if (ref->paramconstraints) {
3095 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3096 fprintf(file," param %d:\n",i);
3097 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3101 fprintf(file," (empty)\n");
3105 #endif /* !defined(NDEBUG) */
3109 * These are local overrides for various environment variables in Emacs.
3110 * Please do not remove this and leave it at the end of the file, where
3111 * Emacs will automagically detect them.
3112 * ---------------------------------------------------------------------
3115 * indent-tabs-mode: t
3119 * vim:noexpandtab:sw=4:ts=4: