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 8288 2007-08-10 15:12:00Z twisti $
36 #include "mm/memory.h"
38 #include "vm/access.h"
39 #include "vm/exceptions.h"
40 #include "vm/global.h"
41 #include "vm/primitive.h"
42 #include "vm/resolve.h"
44 #include "vm/jit/jit.h"
45 #include "vm/jit/verify/typeinfo.h"
47 #include "vmcore/classcache.h"
48 #include "vmcore/descriptor.h"
49 #include "vmcore/linker.h"
50 #include "vmcore/loader.h"
51 #include "vmcore/options.h"
54 /******************************************************************************/
56 /******************************************************************************/
58 /*#define RESOLVE_VERBOSE*/
60 /******************************************************************************/
61 /* CLASS RESOLUTION */
62 /******************************************************************************/
64 /* resolve_class_from_name *****************************************************
66 Resolve a symbolic class reference
69 referer..........the class containing the reference
70 refmethod........the method from which resolution was triggered
71 (may be NULL if not applicable)
72 classname........class name to resolve
73 mode.............mode of resolution:
74 resolveLazy...only resolve if it does not
75 require loading classes
76 resolveEager..load classes if necessary
77 checkaccess......if true, access rights to the class are checked
78 link.............if true, guarantee that the returned class, if any,
82 *result..........set to result of resolution, or to NULL if
83 the reference has not been resolved
84 In the case of an exception, *result is
85 guaranteed to be set to NULL.
88 true.............everything ok
89 (*result may still be NULL for resolveLazy)
90 false............an exception has been thrown
93 The returned class is *not* guaranteed to be linked!
94 (It is guaranteed to be loaded, though.)
96 *******************************************************************************/
98 bool resolve_class_from_name(classinfo *referer,
99 methodinfo *refmethod,
116 assert(mode == resolveLazy || mode == resolveEager);
120 #ifdef RESOLVE_VERBOSE
121 printf("resolve_class_from_name(");
122 utf_fprint_printable_ascii(stdout,referer->name);
123 printf(",%p,",(void*)referer->classloader);
124 utf_fprint_printable_ascii(stdout,classname);
125 printf(",%d,%d)\n",(int)checkaccess,(int)link);
128 /* lookup if this class has already been loaded */
130 cls = classcache_lookup(referer->classloader, classname);
132 #ifdef RESOLVE_VERBOSE
133 printf(" lookup result: %p\n",(void*)cls);
137 /* resolve array types */
139 if (classname->text[0] == '[') {
140 utf_ptr = classname->text + 1;
141 len = classname->blength - 1;
143 /* classname is an array type name */
151 /* the component type is a reference type */
152 /* resolve the component type */
153 if (!resolve_class_from_name(referer,refmethod,
154 utf_new(utf_ptr,len),
155 mode,checkaccess,link,&cls))
156 return false; /* exception */
158 assert(mode == resolveLazy);
159 return true; /* be lazy */
161 /* create the array class */
162 cls = class_array_of(cls,false);
164 return false; /* exception */
168 /* the class has not been loaded, yet */
169 if (mode == resolveLazy)
170 return true; /* be lazy */
173 #ifdef RESOLVE_VERBOSE
174 printf(" loading...\n");
180 cls = load_class_from_classloader(classname, referer->classloader);
183 /* If the exception is a ClassNotFoundException,
184 convert it to a NoClassDefFoundError. */
186 exceptions_classnotfoundexception_to_noclassdeffounderror();
193 /* the class is now loaded */
195 assert(cls->state & CLASS_LOADED);
197 #ifdef RESOLVE_VERBOSE
198 printf(" checking access rights...\n");
201 /* check access rights of referer to refered class */
203 if (checkaccess && !access_is_accessible_class(referer,cls)) {
205 utf_bytes(cls->name) +
206 utf_bytes(referer->name) +
209 msg = MNEW(char, msglen);
211 strcpy(msg, "class is not accessible (");
212 utf_cat_classname(msg, cls->name);
213 strcat(msg, " from ");
214 utf_cat_classname(msg, referer->name);
217 u = utf_new_char(msg);
219 MFREE(msg, char, msglen);
221 exceptions_throw_illegalaccessexception(u);
223 return false; /* exception */
226 /* link the class if necessary */
228 if (!(cls->state & CLASS_LINKED))
229 if (!link_class(cls))
230 return false; /* exception */
232 assert(cls->state & CLASS_LINKED);
235 /* resolution succeeds */
236 #ifdef RESOLVE_VERBOSE
237 printf(" success.\n");
243 /* resolve_classref ************************************************************
245 Resolve a symbolic class reference
248 refmethod........the method from which resolution was triggered
249 (may be NULL if not applicable)
250 ref..............class reference
251 mode.............mode of resolution:
252 resolveLazy...only resolve if it does not
253 require loading classes
254 resolveEager..load classes if necessary
255 checkaccess......if true, access rights to the class are checked
256 link.............if true, guarantee that the returned class, if any,
260 *result..........set to result of resolution, or to NULL if
261 the reference has not been resolved
262 In the case of an exception, *result is
263 guaranteed to be set to NULL.
266 true.............everything ok
267 (*result may still be NULL for resolveLazy)
268 false............an exception has been thrown
270 *******************************************************************************/
272 bool resolve_classref(methodinfo *refmethod,
273 constant_classref *ref,
279 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
282 /* resolve_classref_or_classinfo ***********************************************
284 Resolve a symbolic class reference if necessary
286 NOTE: If given, refmethod->class is used as the referring class.
287 Otherwise, cls.ref->referer is used.
290 refmethod........the method from which resolution was triggered
291 (may be NULL if not applicable)
292 cls..............class reference or classinfo
293 mode.............mode of resolution:
294 resolveLazy...only resolve if it does not
295 require loading classes
296 resolveEager..load classes if necessary
297 checkaccess......if true, access rights to the class are checked
298 link.............if true, guarantee that the returned class, if any,
302 *result..........set to result of resolution, or to NULL if
303 the reference has not been resolved
304 In the case of an exception, *result is
305 guaranteed to be set to NULL.
308 true.............everything ok
309 (*result may still be NULL for resolveLazy)
310 false............an exception has been thrown
312 *******************************************************************************/
314 bool resolve_classref_or_classinfo(methodinfo *refmethod,
315 classref_or_classinfo cls,
325 assert(mode == resolveEager || mode == resolveLazy);
328 #ifdef RESOLVE_VERBOSE
329 printf("resolve_classref_or_classinfo(");
330 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
331 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
336 if (IS_CLASSREF(cls)) {
337 /* we must resolve this reference */
339 /* determine which class to use as the referer */
341 /* Common cases are refmethod == NULL or both referring classes */
342 /* being the same, so the referer usually is cls.ref->referer. */
343 /* There is one important case where it is not: When we do a */
344 /* deferred assignability check to a formal argument of a method, */
345 /* we must use refmethod->class (the caller's class) to resolve */
346 /* the type of the formal argument. */
348 referer = (refmethod) ? refmethod->class : cls.ref->referer;
350 if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
351 mode, checkaccess, link, &c))
352 goto return_exception;
355 /* cls has already been resolved */
357 assert(c->state & CLASS_LOADED);
359 assert(c || (mode == resolveLazy));
362 return true; /* be lazy */
365 assert(c->state & CLASS_LOADED);
368 if (!(c->state & CLASS_LINKED))
370 goto return_exception;
372 assert(c->state & CLASS_LINKED);
385 /* resolve_classref_or_classinfo_eager *****************************************
387 Resolve a symbolic class reference eagerly if necessary.
388 No attempt is made to link the class.
391 cls..............class reference or classinfo
392 checkaccess......if true, access rights to the class are checked
395 classinfo *......the resolved class
396 NULL.............an exception has been thrown
398 *******************************************************************************/
400 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
405 if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
412 /* resolve_class_from_typedesc *************************************************
414 Return a classinfo * for the given type descriptor
417 d................type descriptor
418 checkaccess......if true, access rights to the class are checked
419 link.............if true, guarantee that the returned class, if any,
422 *result..........set to result of resolution, or to NULL if
423 the reference has not been resolved
424 In the case of an exception, *result is
425 guaranteed to be set to NULL.
428 true.............everything ok
429 false............an exception has been thrown
432 This function always resolves eagerly.
434 *******************************************************************************/
436 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
445 #ifdef RESOLVE_VERBOSE
446 printf("resolve_class_from_typedesc(");
447 descriptor_debug_print_typedesc(stdout,d);
448 printf(",%i,%i)\n",(int)checkaccess,(int)link);
451 if (d->type == TYPE_ADR) {
452 /* a reference type */
454 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
455 resolveEager,checkaccess,link,&cls))
456 return false; /* exception */
459 /* a primitive type */
461 cls = primitive_class_get_by_type(d->decltype);
463 assert(cls->state & CLASS_LOADED);
465 if (!(cls->state & CLASS_LINKED))
466 if (!link_class(cls))
467 return false; /* exception */
471 assert(cls->state & CLASS_LOADED);
472 assert(!link || (cls->state & CLASS_LINKED));
474 #ifdef RESOLVE_VERBOSE
475 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
482 /******************************************************************************/
483 /* SUBTYPE SET CHECKS */
484 /******************************************************************************/
486 /* resolve_subtype_check *******************************************************
488 Resolve the given types lazily and perform a subtype check
491 refmethod........the method triggering the resolution
492 subtype..........checked to be a subtype of supertype
493 supertype........the super type to check agaings
494 mode.............mode of resolution:
495 resolveLazy...only resolve if it does not
496 require loading classes
497 resolveEager..load classes if necessary
498 error............which type of exception to throw if
499 the test fails. May be:
500 resolveLinkageError, or
501 resolveIllegalAccessError
502 IMPORTANT: If error==resolveIllegalAccessError,
503 then array types are not checked.
506 resolveSucceeded.....the check succeeded
507 resolveDeferred......the check could not be performed due to
508 unresolved types. (This can only happen for
509 mode == resolveLazy.)
510 resolveFailed........the check failed, an exception has been thrown.
513 The types are resolved first, so any
514 exception which may occurr during resolution may
515 be thrown by this function.
517 *******************************************************************************/
519 #if defined(ENABLE_VERIFIER)
520 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
521 classref_or_classinfo subtype,
522 classref_or_classinfo supertype,
535 assert(supertype.any);
536 assert(mode == resolveLazy || mode == resolveEager);
537 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
539 /* resolve the subtype */
541 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
542 /* the subclass could not be resolved. therefore we are sure that */
543 /* no instances of this subclass will ever exist -> skip this test */
544 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
545 exceptions_clear_exception();
546 return resolveSucceeded;
549 return resolveDeferred; /* be lazy */
551 assert(subclass->state & CLASS_LINKED);
553 /* do not check access to protected members of arrays */
555 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
556 return resolveSucceeded;
559 /* perform the subtype check */
561 typeinfo_init_classinfo(&subti,subclass);
563 r = typeinfo_is_assignable_to_class(&subti,supertype);
564 if (r == typecheck_FAIL)
565 return resolveFailed; /* failed, exception is already set */
567 if (r == typecheck_MAYBE) {
568 assert(IS_CLASSREF(supertype));
569 if (mode == resolveEager) {
570 if (!resolve_classref_or_classinfo(refmethod,supertype,
571 resolveEager,false,true,
574 return resolveFailed;
576 assert(supertype.cls);
580 return resolveDeferred; /* be lazy */
584 /* sub class relationship is false */
586 #if defined(RESOLVE_VERBOSE)
587 printf("SUBTYPE CHECK FAILED!\n");
591 utf_bytes(subclass->name) +
592 utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
595 msg = MNEW(char, msglen);
597 strcpy(msg, (error == resolveIllegalAccessError) ?
598 "illegal access to protected member (" :
599 "subtype constraint violated (");
601 utf_cat_classname(msg, subclass->name);
602 strcat(msg, " is not a subclass of ");
603 utf_cat_classname(msg, CLASSREF_OR_CLASSINFO_NAME(supertype));
606 u = utf_new_char(msg);
608 if (error == resolveIllegalAccessError)
609 exceptions_throw_illegalaccessexception(u);
611 exceptions_throw_linkageerror(msg, NULL);
613 /* ATTENTION: We probably need msg for
614 exceptions_throw_linkageerror. */
616 MFREE(msg, char, msglen);
618 return resolveFailed; /* exception */
623 return resolveSucceeded;
625 #endif /* defined(ENABLE_VERIFIER) */
627 /* resolve_lazy_subtype_checks *************************************************
629 Resolve the types to check lazily and perform subtype checks
632 refmethod........the method triggering the resolution
633 subtinfo.........the typeinfo containing the subtypes
634 supertype........the supertype to test againgst
635 mode.............mode of resolution:
636 resolveLazy...only resolve if it does not
637 require loading classes
638 resolveEager..load classes if necessary
639 error............which type of exception to throw if
640 the test fails. May be:
641 resolveLinkageError, or
642 resolveIllegalAccessError
643 IMPORTANT: If error==resolveIllegalAccessError,
644 then array types in the set are skipped.
647 resolveSucceeded.....the check succeeded
648 resolveDeferred......the check could not be performed due to
650 resolveFailed........the check failed, an exception has been thrown.
653 The references in the set are resolved first, so any
654 exception which may occurr during resolution may
655 be thrown by this function.
657 *******************************************************************************/
659 #if defined(ENABLE_VERIFIER)
660 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
662 classref_or_classinfo supertype,
667 resolve_result_t result;
671 assert(supertype.any);
672 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
674 /* returnAddresses are illegal here */
676 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
677 exceptions_throw_verifyerror(refmethod,
678 "Invalid use of returnAddress");
679 return resolveFailed;
682 /* uninitialized objects are illegal here */
684 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
685 exceptions_throw_verifyerror(refmethod,
686 "Invalid use of uninitialized object");
687 return resolveFailed;
690 /* the nulltype is always assignable */
692 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
693 return resolveSucceeded;
695 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
697 if (supertype.cls == class_java_lang_Object
698 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
699 && refmethod->class->classloader == NULL))
701 return resolveSucceeded;
704 if (subtinfo->merged) {
706 /* for a merged type we have to do a series of checks */
708 count = subtinfo->merged->count;
709 for (i=0; i<count; ++i) {
710 classref_or_classinfo c = subtinfo->merged->list[i];
711 if (subtinfo->dimension > 0) {
712 /* a merge of array types */
713 /* the merged list contains the possible _element_ types, */
714 /* so we have to create array types with these elements. */
715 if (IS_CLASSREF(c)) {
716 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
719 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
723 /* do the subtype check against the type c */
725 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
726 if (result != resolveSucceeded)
732 /* a single type, this is the common case, hopefully */
734 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
735 == CLASSREF_OR_CLASSINFO_NAME(supertype))
737 /* the class names are the same */
738 /* equality is guaranteed by the loading constraints */
739 return resolveSucceeded;
743 /* some other type name, try to perform the check lazily */
745 return resolve_subtype_check(refmethod,
746 subtinfo->typeclass,supertype,
753 return resolveSucceeded;
755 #endif /* defined(ENABLE_VERIFIER) */
757 /* resolve_and_check_subtype_set ***********************************************
759 Resolve the references in the given set and test subtype relationships
762 refmethod........the method triggering the resolution
763 ref..............a set of class/interface references
765 typeref..........the type to test against the set
766 mode.............mode of resolution:
767 resolveLazy...only resolve if it does not
768 require loading classes
769 resolveEager..load classes if necessary
770 error............which type of exception to throw if
771 the test fails. May be:
772 resolveLinkageError, or
773 resolveIllegalAccessError
774 IMPORTANT: If error==resolveIllegalAccessError,
775 then array types in the set are skipped.
778 resolveSucceeded.....the check succeeded
779 resolveDeferred......the check could not be performed due to
780 unresolved types. (This can only happen if
781 mode == resolveLazy.)
782 resolveFailed........the check failed, an exception has been thrown.
785 The references in the set are resolved first, so any
786 exception which may occurr during resolution may
787 be thrown by this function.
789 *******************************************************************************/
791 #if defined(ENABLE_VERIFIER)
792 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
793 unresolved_subtype_set *ref,
794 classref_or_classinfo typeref,
798 classref_or_classinfo *setp;
799 typecheck_result checkresult;
804 assert(mode == resolveLazy || mode == resolveEager);
805 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
807 #if defined(RESOLVE_VERBOSE)
808 printf("resolve_and_check_subtype_set:\n");
809 unresolved_subtype_set_debug_dump(ref, stdout);
810 if (IS_CLASSREF(typeref))
811 class_classref_println(typeref.ref);
813 class_println(typeref.cls);
816 setp = ref->subtyperefs;
818 /* an empty set of tests always succeeds */
819 if (!setp || !setp->any) {
820 return resolveSucceeded;
823 /* first resolve the type if necessary */
824 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
825 return resolveFailed; /* exception */
827 return resolveDeferred; /* be lazy */
829 assert(typeref.cls->state & CLASS_LINKED);
831 /* iterate over the set members */
833 for (; setp->any; ++setp) {
834 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
835 #if defined(RESOLVE_VERBOSE)
836 if (checkresult != resolveSucceeded)
837 printf("SUBTYPE CHECK FAILED!\n");
839 if (checkresult != resolveSucceeded)
844 return resolveSucceeded;
846 #endif /* defined(ENABLE_VERIFIER) */
848 /******************************************************************************/
849 /* CLASS RESOLUTION */
850 /******************************************************************************/
852 /* resolve_class ***************************************************************
854 Resolve an unresolved class reference. The class is also linked.
857 ref..............struct containing the reference
858 mode.............mode of resolution:
859 resolveLazy...only resolve if it does not
860 require loading classes
861 resolveEager..load classes if necessary
862 checkaccess......if true, access rights to the class are checked
865 *result..........set to the result of resolution, or to NULL if
866 the reference has not been resolved
867 In the case of an exception, *result is
868 guaranteed to be set to NULL.
871 true.............everything ok
872 (*result may still be NULL for resolveLazy)
873 false............an exception has been thrown
875 *******************************************************************************/
877 #ifdef ENABLE_VERIFIER
878 bool resolve_class(unresolved_class *ref,
884 resolve_result_t checkresult;
888 assert(mode == resolveLazy || mode == resolveEager);
892 #ifdef RESOLVE_VERBOSE
893 unresolved_class_debug_dump(ref,stdout);
896 /* first we must resolve the class */
897 if (!resolve_classref(ref->referermethod,
898 ref->classref,mode,checkaccess,true,&cls))
900 /* the class reference could not be resolved */
901 return false; /* exception */
904 return true; /* be lazy */
907 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
909 /* now we check the subtype constraints */
911 checkresult = resolve_and_check_subtype_set(ref->referermethod,
912 &(ref->subtypeconstraints),
913 CLASSREF_OR_CLASSINFO(cls),
915 resolveLinkageError);
916 if (checkresult != resolveSucceeded)
917 return (bool) checkresult;
923 #endif /* ENABLE_VERIFIER */
925 /* resolve_classref_eager ******************************************************
927 Resolve an unresolved class reference eagerly. The class is also linked and
928 access rights to the class are checked.
931 ref..............constant_classref to the class
934 classinfo * to the class, or
935 NULL if an exception has been thrown
937 *******************************************************************************/
939 classinfo * resolve_classref_eager(constant_classref *ref)
943 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
949 /* resolve_classref_eager_nonabstract ******************************************
951 Resolve an unresolved class reference eagerly. The class is also linked and
952 access rights to the class are checked. A check is performed that the class
956 ref..............constant_classref to the class
959 classinfo * to the class, or
960 NULL if an exception has been thrown
962 *******************************************************************************/
964 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
968 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
971 /* ensure that the class is not abstract */
973 if (c->flags & ACC_ABSTRACT) {
974 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
981 /* resolve_class_eager *********************************************************
983 Resolve an unresolved class reference eagerly. The class is also linked and
984 access rights to the class are 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(unresolved_class *ref)
1000 if (!resolve_class(ref,resolveEager,true,&c))
1005 #endif /* ENABLE_VERIFIER */
1007 /* resolve_class_eager_no_access_check *****************************************
1009 Resolve an unresolved class reference eagerly. The class is also linked.
1010 Access rights are _not_ checked.
1013 ref..............struct containing the reference
1016 classinfo * to the class, or
1017 NULL if an exception has been thrown
1019 *******************************************************************************/
1021 #ifdef ENABLE_VERIFIER
1022 classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
1026 if (!resolve_class(ref, resolveEager, false, &c))
1031 #endif /* ENABLE_VERIFIER */
1033 /******************************************************************************/
1034 /* FIELD RESOLUTION */
1035 /******************************************************************************/
1037 /* resolve_field_verifier_checks *******************************************
1039 Do the verifier checks necessary after field has been resolved.
1042 refmethod........the method containing the reference
1043 fieldref.........the field reference
1044 container........the class where the field was found
1045 fi...............the fieldinfo of the resolved field
1046 instanceti.......instance typeinfo, if available
1047 valueti..........value typeinfo, if available
1048 isstatic.........true if this is a *STATIC* instruction
1049 isput............true if this is a PUT* instruction
1052 resolveSucceeded....everything ok
1053 resolveDeferred.....tests could not be done, have been deferred
1054 resolveFailed.......exception has been thrown
1056 *******************************************************************************/
1058 #if defined(ENABLE_VERIFIER)
1059 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
1060 constant_FMIref *fieldref,
1061 classinfo *container,
1063 typeinfo *instanceti,
1068 classinfo *declarer;
1070 resolve_result_t result;
1071 constant_classref *fieldtyperef;
1081 /* get the classinfos and the field type */
1083 referer = refmethod->class;
1086 declarer = fi->class;
1088 assert(referer->state & CLASS_LINKED);
1090 fieldtyperef = fieldref->parseddesc.fd->classref;
1095 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1098 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1099 /* a static field is accessed via an instance, or vice versa */
1100 exceptions_throw_incompatibleclasschangeerror(declarer,
1101 (fi->flags & ACC_STATIC)
1102 ? "static field accessed via instance"
1103 : "instance field accessed without instance");
1105 return resolveFailed;
1108 /* check access rights */
1110 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1112 utf_bytes(declarer->name) +
1113 utf_bytes(fi->name) +
1114 utf_bytes(referer->name) +
1117 msg = MNEW(char, msglen);
1119 strcpy(msg, "field is not accessible (");
1120 utf_cat_classname(msg, declarer->name);
1122 utf_cat(msg, fi->name);
1123 strcat(msg, " from ");
1124 utf_cat_classname(msg, referer->name);
1127 u = utf_new_char(msg);
1129 MFREE(msg, char, msglen);
1131 exceptions_throw_illegalaccessexception(u);
1133 return resolveFailed; /* exception */
1136 /* for non-static methods we have to check the constraints on the */
1143 /* The instanceslot must contain a reference to a non-array type */
1145 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1146 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1147 return resolveFailed;
1149 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1150 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1151 return resolveFailed;
1154 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1156 /* The instruction writes a field in an uninitialized object. */
1157 /* This is only allowed when a field of an uninitialized 'this' object is */
1158 /* written inside an initialization method */
1160 classinfo *initclass;
1161 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1164 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1165 return resolveFailed;
1168 /* XXX check that class of field == refmethod->class */
1169 initclass = referer; /* XXX classrefs */
1170 assert(initclass->state & CLASS_LINKED);
1172 typeinfo_init_classinfo(&tinfo, initclass);
1176 insttip = instanceti;
1179 result = resolve_lazy_subtype_checks(refmethod,
1181 CLASSREF_OR_CLASSINFO(container),
1182 resolveLinkageError);
1183 if (result != resolveSucceeded)
1186 /* check protected access */
1188 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1190 result = resolve_lazy_subtype_checks(refmethod,
1192 CLASSREF_OR_CLASSINFO(referer),
1193 resolveIllegalAccessError);
1194 if (result != resolveSucceeded)
1200 /* for PUT* instructions we have to check the constraints on the value type */
1203 assert(fieldtyperef);
1205 /* check subtype constraints */
1206 result = resolve_lazy_subtype_checks(refmethod,
1208 CLASSREF_OR_CLASSINFO(fieldtyperef),
1209 resolveLinkageError);
1211 if (result != resolveSucceeded)
1215 /* impose loading constraint on field type */
1217 if (fi->type == TYPE_ADR) {
1218 assert(fieldtyperef);
1219 if (!classcache_add_constraint(declarer->classloader,
1220 referer->classloader,
1221 fieldtyperef->name))
1222 return resolveFailed;
1225 /* XXX impose loading constraint on instance? */
1228 return resolveSucceeded;
1230 #endif /* defined(ENABLE_VERIFIER) */
1232 /* resolve_field_lazy **********************************************************
1234 Resolve an unresolved field reference lazily
1236 NOTE: This function does NOT do any verification checks. In case of a
1237 successful resolution, you must call resolve_field_verifier_checks
1238 in order to perform the necessary checks!
1241 refmethod........the referer method
1242 fieldref.........the field reference
1245 resolveSucceeded.....the reference has been resolved
1246 resolveDeferred......the resolving could not be performed lazily
1247 resolveFailed........resolving failed, an exception has been thrown.
1249 *******************************************************************************/
1251 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1252 constant_FMIref *fieldref)
1255 classinfo *container;
1260 /* the class containing the reference */
1262 referer = refmethod->class;
1265 /* check if the field itself is already resolved */
1267 if (IS_FMIREF_RESOLVED(fieldref))
1268 return resolveSucceeded;
1270 /* first we must resolve the class containg the field */
1272 /* XXX can/may lazyResolving trigger linking? */
1274 if (!resolve_class_from_name(referer, refmethod,
1275 fieldref->p.classref->name, resolveLazy, true, true, &container))
1277 /* the class reference could not be resolved */
1278 return resolveFailed; /* exception */
1281 return resolveDeferred; /* be lazy */
1283 assert(container->state & CLASS_LINKED);
1285 /* now we must find the declaration of the field in `container`
1286 * or one of its superclasses */
1288 fi = class_resolvefield(container,
1289 fieldref->name, fieldref->descriptor,
1292 /* The field does not exist. But since we were called lazily, */
1293 /* this error must not be reported now. (It will be reported */
1294 /* if eager resolving of this field is ever tried.) */
1296 exceptions_clear_exception();
1297 return resolveDeferred; /* be lazy */
1300 /* cache the result of the resolution */
1302 fieldref->p.field = fi;
1305 return resolveSucceeded;
1308 /* resolve_field ***************************************************************
1310 Resolve an unresolved field reference
1313 ref..............struct containing the reference
1314 mode.............mode of resolution:
1315 resolveLazy...only resolve if it does not
1316 require loading classes
1317 resolveEager..load classes if necessary
1320 *result..........set to the result of resolution, or to NULL if
1321 the reference has not been resolved
1322 In the case of an exception, *result is
1323 guaranteed to be set to NULL.
1326 true.............everything ok
1327 (*result may still be NULL for resolveLazy)
1328 false............an exception has been thrown
1330 *******************************************************************************/
1332 bool resolve_field(unresolved_field *ref,
1333 resolve_mode_t mode,
1337 classinfo *container;
1338 classinfo *declarer;
1339 constant_classref *fieldtyperef;
1341 resolve_result_t checkresult;
1345 assert(mode == resolveLazy || mode == resolveEager);
1349 #ifdef RESOLVE_VERBOSE
1350 unresolved_field_debug_dump(ref,stdout);
1353 /* the class containing the reference */
1355 referer = ref->referermethod->class;
1358 /* check if the field itself is already resolved */
1359 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1360 fi = ref->fieldref->p.field;
1361 container = fi->class;
1362 goto resolved_the_field;
1365 /* first we must resolve the class containg the field */
1366 if (!resolve_class_from_name(referer,ref->referermethod,
1367 ref->fieldref->p.classref->name,mode,true,true,&container))
1369 /* the class reference could not be resolved */
1370 return false; /* exception */
1373 return true; /* be lazy */
1376 assert(container->state & CLASS_LOADED);
1377 assert(container->state & CLASS_LINKED);
1379 /* now we must find the declaration of the field in `container`
1380 * or one of its superclasses */
1382 #ifdef RESOLVE_VERBOSE
1383 printf(" resolving field in class...\n");
1386 fi = class_resolvefield(container,
1387 ref->fieldref->name,ref->fieldref->descriptor,
1390 if (mode == resolveLazy) {
1391 /* The field does not exist. But since we were called lazily, */
1392 /* this error must not be reported now. (It will be reported */
1393 /* if eager resolving of this field is ever tried.) */
1395 exceptions_clear_exception();
1396 return true; /* be lazy */
1399 return false; /* exception */
1402 /* cache the result of the resolution */
1403 ref->fieldref->p.field = fi;
1407 #ifdef ENABLE_VERIFIER
1408 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1409 /* that no missing parts of an instruction will be accessed. */
1411 checkresult = resolve_field_verifier_checks(
1416 NULL, /* instanceti, handled by constraints below */
1417 NULL, /* valueti, handled by constraints below */
1418 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1419 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1421 if (checkresult != resolveSucceeded)
1422 return (bool) checkresult;
1424 declarer = fi->class;
1426 assert(declarer->state & CLASS_LOADED);
1427 assert(declarer->state & CLASS_LINKED);
1429 /* for non-static accesses we have to check the constraints on the */
1432 if (!(ref->flags & RESOLVE_STATIC)) {
1433 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1434 &(ref->instancetypes),
1435 CLASSREF_OR_CLASSINFO(container),
1436 mode, resolveLinkageError);
1437 if (checkresult != resolveSucceeded)
1438 return (bool) checkresult;
1441 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1443 /* for PUT* instructions we have to check the constraints on the value type */
1444 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1445 assert(fieldtyperef);
1446 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1447 /* check subtype constraints */
1448 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1449 &(ref->valueconstraints),
1450 CLASSREF_OR_CLASSINFO(fieldtyperef),
1451 mode, resolveLinkageError);
1452 if (checkresult != resolveSucceeded)
1453 return (bool) checkresult;
1457 /* check protected access */
1458 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1459 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1460 &(ref->instancetypes),
1461 CLASSREF_OR_CLASSINFO(referer),
1463 resolveIllegalAccessError);
1464 if (checkresult != resolveSucceeded)
1465 return (bool) checkresult;
1469 #endif /* ENABLE_VERIFIER */
1477 /* resolve_field_eager *********************************************************
1479 Resolve an unresolved field reference eagerly.
1482 ref..............struct containing the reference
1485 fieldinfo * to the field, or
1486 NULL if an exception has been thrown
1488 *******************************************************************************/
1490 fieldinfo * resolve_field_eager(unresolved_field *ref)
1494 if (!resolve_field(ref,resolveEager,&fi))
1500 /******************************************************************************/
1501 /* METHOD RESOLUTION */
1502 /******************************************************************************/
1504 /* resolve_method_invokespecial_lookup *****************************************
1506 Do the special lookup for methods invoked by INVOKESPECIAL
1509 refmethod........the method containing the reference
1510 mi...............the methodinfo of the resolved method
1513 a methodinfo *...the result of the lookup,
1514 NULL.............an exception has been thrown
1516 *******************************************************************************/
1518 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1521 classinfo *declarer;
1527 /* get referer and declarer classes */
1529 referer = refmethod->class;
1532 declarer = mi->class;
1534 assert(referer->state & CLASS_LINKED);
1536 /* checks for INVOKESPECIAL: */
1537 /* for <init> and methods of the current class we don't need any */
1538 /* special checks. Otherwise we must verify that the called method */
1539 /* belongs to a super class of the current class */
1541 if ((referer != declarer) && (mi->name != utf_init)) {
1542 /* check that declarer is a super class of the current class */
1544 if (!class_issubclass(referer,declarer)) {
1545 exceptions_throw_verifyerror(refmethod,
1546 "INVOKESPECIAL calling non-super class method");
1550 /* if the referer has ACC_SUPER set, we must do the special */
1551 /* lookup starting with the direct super class of referer */
1553 if ((referer->flags & ACC_SUPER) != 0) {
1554 mi = class_resolvemethod(referer->super.cls,
1559 /* the spec calls for an AbstractMethodError in this case */
1561 exceptions_throw_abstractmethoderror();
1572 /* resolve_method_verifier_checks ******************************************
1574 Do the verifier checks necessary after a method has been resolved.
1577 refmethod........the method containing the reference
1578 methodref........the method reference
1579 mi...............the methodinfo of the resolved method
1580 invokestatic.....true if the method is invoked by INVOKESTATIC
1583 resolveSucceeded....everything ok
1584 resolveDeferred.....tests could not be done, have been deferred
1585 resolveFailed.......exception has been thrown
1587 *******************************************************************************/
1589 #if defined(ENABLE_VERIFIER)
1590 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1591 constant_FMIref *methodref,
1595 classinfo *declarer;
1605 #ifdef RESOLVE_VERBOSE
1606 printf("resolve_method_verifier_checks\n");
1607 printf(" flags: %02x\n",mi->flags);
1610 /* get the classinfos and the method descriptor */
1612 referer = refmethod->class;
1615 declarer = mi->class;
1620 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1621 /* a static method is accessed via an instance, or vice versa */
1622 exceptions_throw_incompatibleclasschangeerror(declarer,
1623 (mi->flags & ACC_STATIC)
1624 ? "static method called via instance"
1625 : "instance method called without instance");
1627 return resolveFailed;
1630 /* check access rights */
1632 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1633 /* XXX clean this up. this should be in exceptions.c */
1636 utf_bytes(declarer->name) +
1637 utf_bytes(mi->name) +
1638 utf_bytes(mi->descriptor) +
1639 utf_bytes(referer->name) +
1642 msg = MNEW(char, msglen);
1644 strcpy(msg, "method is not accessible (");
1645 utf_cat_classname(msg, declarer->name);
1647 utf_cat(msg, mi->name);
1648 utf_cat(msg, mi->descriptor);
1649 strcat(msg, " from ");
1650 utf_cat_classname(msg, referer->name);
1653 u = utf_new_char(msg);
1655 MFREE(msg, char, msglen);
1657 exceptions_throw_illegalaccessexception(u);
1659 return resolveFailed; /* exception */
1664 return resolveSucceeded;
1666 #endif /* defined(ENABLE_VERIFIER) */
1669 /* resolve_method_instance_type_checks *****************************************
1671 Check the instance type of a method invocation.
1674 refmethod........the method containing the reference
1675 mi...............the methodinfo of the resolved method
1676 instanceti.......typeinfo of the instance slot
1677 invokespecial....true if the method is invoked by INVOKESPECIAL
1680 resolveSucceeded....everything ok
1681 resolveDeferred.....tests could not be done, have been deferred
1682 resolveFailed.......exception has been thrown
1684 *******************************************************************************/
1686 #if defined(ENABLE_VERIFIER)
1687 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1689 typeinfo *instanceti,
1694 resolve_result_t result;
1696 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1697 { /* XXX clean up */
1698 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1699 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1700 : CLASSREF_OR_CLASSINFO(refmethod->class);
1702 if (!typeinfo_init_class(tip, initclass))
1709 result = resolve_lazy_subtype_checks(refmethod,
1711 CLASSREF_OR_CLASSINFO(mi->class),
1712 resolveLinkageError);
1713 if (result != resolveSucceeded)
1716 /* check protected access */
1718 /* XXX use other `declarer` than mi->class? */
1719 if (((mi->flags & ACC_PROTECTED) != 0)
1720 && !SAME_PACKAGE(mi->class, refmethod->class))
1722 result = resolve_lazy_subtype_checks(refmethod,
1724 CLASSREF_OR_CLASSINFO(refmethod->class),
1725 resolveIllegalAccessError);
1726 if (result != resolveSucceeded)
1732 return resolveSucceeded;
1734 #endif /* defined(ENABLE_VERIFIER) */
1737 /* resolve_method_param_type_checks ********************************************
1739 Check non-instance parameter types of a method invocation.
1742 jd...............jitdata of the method doing the call
1743 refmethod........the method containing the reference
1744 iptr.............the invoke instruction
1745 mi...............the methodinfo of the resolved method
1746 invokestatic.....true if the method is invoked by INVOKESTATIC
1749 resolveSucceeded....everything ok
1750 resolveDeferred.....tests could not be done, have been deferred
1751 resolveFailed.......exception has been thrown
1753 *******************************************************************************/
1755 #if defined(ENABLE_VERIFIER)
1756 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1757 methodinfo *refmethod,
1763 resolve_result_t result;
1765 typedesc *paramtypes;
1772 instancecount = (invokestatic) ? 0 : 1;
1774 /* check subtype constraints for TYPE_ADR parameters */
1776 md = mi->parseddesc;
1777 paramtypes = md->paramtypes;
1779 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1780 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1781 type = md->paramtypes[i+instancecount].type;
1784 assert(type == param->type);
1786 if (type == TYPE_ADR) {
1787 result = resolve_lazy_subtype_checks(refmethod,
1789 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1790 resolveLinkageError);
1791 if (result != resolveSucceeded)
1798 return resolveSucceeded;
1800 #endif /* defined(ENABLE_VERIFIER) */
1803 /* resolve_method_param_type_checks_stackbased *********************************
1805 Check non-instance parameter types of a method invocation.
1808 refmethod........the method containing the reference
1809 mi...............the methodinfo of the resolved method
1810 invokestatic.....true if the method is invoked by INVOKESTATIC
1811 stack............TOS before the INVOKE instruction
1814 resolveSucceeded....everything ok
1815 resolveDeferred.....tests could not be done, have been deferred
1816 resolveFailed.......exception has been thrown
1818 *******************************************************************************/
1820 #if defined(ENABLE_VERIFIER)
1821 resolve_result_t resolve_method_param_type_checks_stackbased(
1822 methodinfo *refmethod,
1825 typedescriptor *stack)
1827 typedescriptor *param;
1828 resolve_result_t result;
1830 typedesc *paramtypes;
1835 instancecount = (invokestatic) ? 0 : 1;
1837 /* check subtype constraints for TYPE_ADR parameters */
1839 md = mi->parseddesc;
1840 paramtypes = md->paramtypes;
1842 param = stack - (md->paramslots - 1 - instancecount);
1844 for (i = instancecount; i < md->paramcount; ++i) {
1845 type = md->paramtypes[i].type;
1847 assert(type == param->type);
1849 if (type == TYPE_ADR) {
1850 result = resolve_lazy_subtype_checks(refmethod,
1852 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1853 resolveLinkageError);
1854 if (result != resolveSucceeded)
1858 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1863 return resolveSucceeded;
1865 #endif /* defined(ENABLE_VERIFIER) */
1868 /* resolve_method_loading_constraints ******************************************
1870 Impose loading constraints on the parameters and return type of the
1874 referer..........the class refering to the method
1875 mi...............the method
1878 true................everything ok
1879 false...............an exception has been thrown
1881 *******************************************************************************/
1883 #if defined(ENABLE_VERIFIER)
1884 bool resolve_method_loading_constraints(classinfo *referer,
1888 typedesc *paramtypes;
1893 /* impose loading constraints on parameters (including instance) */
1895 md = mi->parseddesc;
1896 paramtypes = md->paramtypes;
1897 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1899 for (i = 0; i < md->paramcount; i++) {
1900 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1901 if (i < instancecount) {
1902 /* The type of the 'this' pointer is the class containing */
1903 /* the method definition. Since container is the same as, */
1904 /* or a subclass of declarer, we also constrain declarer */
1905 /* by transitivity of loading constraints. */
1906 name = mi->class->name;
1909 name = paramtypes[i].classref->name;
1912 /* The caller (referer) and the callee (container) must agree */
1913 /* on the types of the parameters. */
1914 if (!classcache_add_constraint(referer->classloader,
1915 mi->class->classloader, name))
1916 return false; /* exception */
1920 /* impose loading constraint onto return type */
1922 if (md->returntype.type == TYPE_ADR) {
1923 /* The caller (referer) and the callee (container) must agree */
1924 /* on the return type. */
1925 if (!classcache_add_constraint(referer->classloader,
1926 mi->class->classloader,
1927 md->returntype.classref->name))
1928 return false; /* exception */
1935 #endif /* defined(ENABLE_VERIFIER) */
1938 /* resolve_method_lazy *********************************************************
1940 Resolve an unresolved method reference lazily
1942 NOTE: This function does NOT do any verification checks. In case of a
1943 successful resolution, you must call resolve_method_verifier_checks
1944 in order to perform the necessary checks!
1947 refmethod........the referer method
1948 methodref........the method reference
1949 invokespecial....true if this is an INVOKESPECIAL instruction
1952 resolveSucceeded.....the reference has been resolved
1953 resolveDeferred......the resolving could not be performed lazily
1954 resolveFailed........resolving failed, an exception has been thrown.
1956 *******************************************************************************/
1958 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1959 constant_FMIref *methodref,
1963 classinfo *container;
1968 #ifdef RESOLVE_VERBOSE
1969 printf("resolve_method_lazy\n");
1972 /* the class containing the reference */
1974 referer = refmethod->class;
1977 /* check if the method itself is already resolved */
1979 if (IS_FMIREF_RESOLVED(methodref))
1980 return resolveSucceeded;
1982 /* first we must resolve the class containg the method */
1984 if (!resolve_class_from_name(referer, refmethod,
1985 methodref->p.classref->name, resolveLazy, true, true, &container))
1987 /* the class reference could not be resolved */
1988 return resolveFailed; /* exception */
1991 return resolveDeferred; /* be lazy */
1993 assert(container->state & CLASS_LINKED);
1995 /* now we must find the declaration of the method in `container`
1996 * or one of its superclasses */
1998 if (container->flags & ACC_INTERFACE) {
1999 mi = class_resolveinterfacemethod(container,
2001 methodref->descriptor,
2005 mi = class_resolveclassmethod(container,
2007 methodref->descriptor,
2012 /* The method does not exist. But since we were called lazily, */
2013 /* this error must not be reported now. (It will be reported */
2014 /* if eager resolving of this method is ever tried.) */
2016 exceptions_clear_exception();
2017 return resolveDeferred; /* be lazy */
2020 if (invokespecial) {
2021 mi = resolve_method_invokespecial_lookup(refmethod, mi);
2023 return resolveFailed; /* exception */
2026 /* have the method params already been parsed? no, do it. */
2028 if (!mi->parseddesc->params)
2029 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2030 return resolveFailed;
2032 /* cache the result of the resolution */
2034 methodref->p.method = mi;
2038 return resolveSucceeded;
2041 /* resolve_method **************************************************************
2043 Resolve an unresolved method reference
2046 ref..............struct containing the reference
2047 mode.............mode of resolution:
2048 resolveLazy...only resolve if it does not
2049 require loading classes
2050 resolveEager..load classes if necessary
2053 *result..........set to the result of resolution, or to NULL if
2054 the reference has not been resolved
2055 In the case of an exception, *result is
2056 guaranteed to be set to NULL.
2059 true.............everything ok
2060 (*result may still be NULL for resolveLazy)
2061 false............an exception has been thrown
2063 *******************************************************************************/
2065 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2068 classinfo *container;
2069 classinfo *declarer;
2071 typedesc *paramtypes;
2074 resolve_result_t checkresult;
2078 assert(mode == resolveLazy || mode == resolveEager);
2080 #ifdef RESOLVE_VERBOSE
2081 unresolved_method_debug_dump(ref,stdout);
2086 /* the class containing the reference */
2088 referer = ref->referermethod->class;
2091 /* check if the method itself is already resolved */
2093 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2094 mi = ref->methodref->p.method;
2095 container = mi->class;
2096 goto resolved_the_method;
2099 /* first we must resolve the class containing the method */
2101 if (!resolve_class_from_name(referer,ref->referermethod,
2102 ref->methodref->p.classref->name,mode,true,true,&container))
2104 /* the class reference could not be resolved */
2105 return false; /* exception */
2108 return true; /* be lazy */
2111 assert(container->state & CLASS_LINKED);
2113 /* now we must find the declaration of the method in `container`
2114 * or one of its superclasses */
2116 if (container->flags & ACC_INTERFACE) {
2117 mi = class_resolveinterfacemethod(container,
2118 ref->methodref->name,
2119 ref->methodref->descriptor,
2123 mi = class_resolveclassmethod(container,
2124 ref->methodref->name,
2125 ref->methodref->descriptor,
2130 if (mode == resolveLazy) {
2131 /* The method does not exist. But since we were called lazily, */
2132 /* this error must not be reported now. (It will be reported */
2133 /* if eager resolving of this method is ever tried.) */
2135 exceptions_clear_exception();
2136 return true; /* be lazy */
2139 return false; /* exception */ /* XXX set exceptionptr? */
2142 /* { the method reference has been resolved } */
2144 if (ref->flags & RESOLVE_SPECIAL) {
2145 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2147 return false; /* exception */
2150 /* have the method params already been parsed? no, do it. */
2152 if (!mi->parseddesc->params)
2153 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2156 /* cache the resolution */
2158 ref->methodref->p.method = mi;
2160 resolved_the_method:
2162 #ifdef ENABLE_VERIFIER
2165 checkresult = resolve_method_verifier_checks(
2169 (ref->flags & RESOLVE_STATIC));
2171 if (checkresult != resolveSucceeded)
2172 return (bool) checkresult;
2174 /* impose loading constraints on params and return type */
2176 if (!resolve_method_loading_constraints(referer, mi))
2179 declarer = mi->class;
2181 assert(referer->state & CLASS_LINKED);
2183 /* for non-static methods we have to check the constraints on the */
2186 if (!(ref->flags & RESOLVE_STATIC)) {
2187 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2188 &(ref->instancetypes),
2189 CLASSREF_OR_CLASSINFO(container),
2191 resolveLinkageError);
2192 if (checkresult != resolveSucceeded)
2193 return (bool) checkresult;
2200 /* check subtype constraints for TYPE_ADR parameters */
2202 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2203 paramtypes = mi->parseddesc->paramtypes;
2205 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2206 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2207 if (ref->paramconstraints) {
2208 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2209 ref->paramconstraints + i,
2210 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2212 resolveLinkageError);
2213 if (checkresult != resolveSucceeded)
2214 return (bool) checkresult;
2219 /* check protected access */
2221 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2223 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2224 &(ref->instancetypes),
2225 CLASSREF_OR_CLASSINFO(referer),
2227 resolveIllegalAccessError);
2228 if (checkresult != resolveSucceeded)
2229 return (bool) checkresult;
2232 #endif /* ENABLE_VERIFIER */
2239 /* resolve_method_eager ********************************************************
2241 Resolve an unresolved method reference eagerly.
2244 ref..............struct containing the reference
2247 methodinfo * to the method, or
2248 NULL if an exception has been thrown
2250 *******************************************************************************/
2252 methodinfo * resolve_method_eager(unresolved_method *ref)
2256 if (!resolve_method(ref,resolveEager,&mi))
2262 /******************************************************************************/
2263 /* CREATING THE DATA STRUCTURES */
2264 /******************************************************************************/
2266 #ifdef ENABLE_VERIFIER
2267 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2268 methodinfo *refmethod,
2269 unresolved_subtype_set *stset,
2271 utf *declaredclassname)
2279 #ifdef RESOLVE_VERBOSE
2280 printf("unresolved_subtype_set_from_typeinfo\n");
2281 #ifdef TYPEINFO_DEBUG
2282 typeinfo_print(stdout,tinfo,4);
2284 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2288 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2289 exceptions_throw_verifyerror(refmethod,
2290 "Invalid use of returnAddress");
2294 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2295 exceptions_throw_verifyerror(refmethod,
2296 "Invalid use of uninitialized object");
2300 /* the nulltype is always assignable */
2301 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2304 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2305 if (declaredclassname == utf_java_lang_Object
2306 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2311 if (tinfo->merged) {
2312 count = tinfo->merged->count;
2313 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2314 for (i=0; i<count; ++i) {
2315 classref_or_classinfo c = tinfo->merged->list[i];
2316 if (tinfo->dimension > 0) {
2317 /* a merge of array types */
2318 /* the merged list contains the possible _element_ types, */
2319 /* so we have to create array types with these elements. */
2320 if (IS_CLASSREF(c)) {
2321 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2324 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2327 stset->subtyperefs[i] = c;
2329 stset->subtyperefs[count].any = NULL; /* terminate */
2332 if ((IS_CLASSREF(tinfo->typeclass)
2333 ? tinfo->typeclass.ref->name
2334 : tinfo->typeclass.cls->name) == declaredclassname)
2336 /* the class names are the same */
2337 /* equality is guaranteed by the loading constraints */
2341 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2342 stset->subtyperefs[0] = tinfo->typeclass;
2343 stset->subtyperefs[1].any = NULL; /* terminate */
2350 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2353 #endif /* ENABLE_VERIFIER */
2355 /* create_unresolved_class *****************************************************
2357 Create an unresolved_class struct for the given class reference
2360 refmethod........the method triggering the resolution (if any)
2361 classref.........the class reference
2362 valuetype........value type to check against the resolved class
2363 may be NULL, if no typeinfo is available
2366 a pointer to a new unresolved_class struct, or
2367 NULL if an exception has been thrown
2369 *******************************************************************************/
2371 #ifdef ENABLE_VERIFIER
2372 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2373 constant_classref *classref,
2374 typeinfo *valuetype)
2376 unresolved_class *ref;
2378 #ifdef RESOLVE_VERBOSE
2379 printf("create_unresolved_class\n");
2380 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2382 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2383 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2385 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2388 ref = NEW(unresolved_class);
2389 ref->classref = classref;
2390 ref->referermethod = refmethod;
2393 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2394 &(ref->subtypeconstraints),valuetype,classref->name))
2398 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2403 #endif /* ENABLE_VERIFIER */
2405 /* resolve_create_unresolved_field *********************************************
2407 Create an unresolved_field struct for the given field access instruction
2410 referer..........the class containing the reference
2411 refmethod........the method triggering the resolution (if any)
2412 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2415 a pointer to a new unresolved_field struct, or
2416 NULL if an exception has been thrown
2418 *******************************************************************************/
2420 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2421 methodinfo *refmethod,
2424 unresolved_field *ref;
2425 constant_FMIref *fieldref = NULL;
2427 #ifdef RESOLVE_VERBOSE
2428 printf("create_unresolved_field\n");
2429 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2430 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2431 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2434 ref = NEW(unresolved_field);
2436 ref->referermethod = refmethod;
2437 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2439 switch (iptr->opc) {
2441 ref->flags |= RESOLVE_PUTFIELD;
2444 case ICMD_PUTFIELDCONST:
2445 ref->flags |= RESOLVE_PUTFIELD;
2448 case ICMD_PUTSTATIC:
2449 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2452 case ICMD_PUTSTATICCONST:
2453 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2459 case ICMD_GETSTATIC:
2460 ref->flags |= RESOLVE_STATIC;
2463 #if !defined(NDEBUG)
2469 fieldref = iptr->sx.s23.s3.fmiref;
2473 #ifdef RESOLVE_VERBOSE
2474 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2475 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2476 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2477 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2481 ref->fieldref = fieldref;
2486 /* resolve_constrain_unresolved_field ******************************************
2488 Record subtype constraints for a field access.
2491 ref..............the unresolved_field structure of the access
2492 referer..........the class containing the reference
2493 refmethod........the method triggering the resolution (if any)
2494 instanceti.......instance typeinfo, if available
2495 valueti..........value typeinfo, if available
2498 true.............everything ok
2499 false............an exception has been thrown
2501 *******************************************************************************/
2503 #if defined(ENABLE_VERIFIER)
2504 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2506 methodinfo *refmethod,
2507 typeinfo *instanceti,
2510 constant_FMIref *fieldref;
2517 fieldref = ref->fieldref;
2520 #ifdef RESOLVE_VERBOSE
2521 printf("constrain_unresolved_field\n");
2522 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2523 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2524 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2525 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2526 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2527 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2528 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2532 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2533 fd = fieldref->parseddesc.fd;
2536 /* record subtype constraints for the instance type, if any */
2540 /* The instanceslot must contain a reference to a non-array type */
2541 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2542 exceptions_throw_verifyerror(refmethod,
2543 "illegal instruction: field access on non-reference");
2546 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2547 exceptions_throw_verifyerror(refmethod,
2548 "illegal instruction: field access on array");
2552 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2553 TYPEINFO_IS_NEWOBJECT(*instanceti))
2555 /* The instruction writes a field in an uninitialized object. */
2556 /* This is only allowed when a field of an uninitialized 'this' object is */
2557 /* written inside an initialization method */
2559 classinfo *initclass;
2560 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2563 exceptions_throw_verifyerror(refmethod,
2564 "accessing field of uninitialized object");
2567 /* XXX check that class of field == refmethod->class */
2568 initclass = refmethod->class; /* XXX classrefs */
2569 assert(initclass->state & CLASS_LOADED);
2570 assert(initclass->state & CLASS_LINKED);
2572 typeinfo_init_classinfo(&tinfo, initclass);
2576 insttip = instanceti;
2578 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2579 &(ref->instancetypes), insttip,
2580 FIELDREF_CLASSNAME(fieldref)))
2584 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2587 /* record subtype constraints for the value type, if any */
2589 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2591 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2592 &(ref->valueconstraints), valueti,
2593 fieldref->parseddesc.fd->classref->name))
2597 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2602 #endif /* ENABLE_VERIFIER */
2604 /* resolve_create_unresolved_method ********************************************
2606 Create an unresolved_method struct for the given method invocation
2609 referer..........the class containing the reference
2610 refmethod........the method triggering the resolution (if any)
2611 iptr.............the INVOKE* instruction
2614 a pointer to a new unresolved_method struct, or
2615 NULL if an exception has been thrown
2617 *******************************************************************************/
2619 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2620 methodinfo *refmethod,
2621 constant_FMIref *methodref,
2625 unresolved_method *ref;
2629 #ifdef RESOLVE_VERBOSE
2630 printf("create_unresolved_method\n");
2631 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2632 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2633 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2634 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2635 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2638 /* allocate params if necessary */
2639 if (!methodref->parseddesc.md->params)
2640 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2641 (invokestatic) ? ACC_STATIC : ACC_NONE))
2644 /* create the data structure */
2645 ref = NEW(unresolved_method);
2646 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2647 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2648 ref->referermethod = refmethod;
2649 ref->methodref = methodref;
2650 ref->paramconstraints = NULL;
2651 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2657 /* resolve_constrain_unresolved_method_instance ********************************
2659 Record subtype constraints for the instance argument of a method call.
2662 ref..............the unresolved_method structure of the call
2663 referer..........the class containing the reference
2664 refmethod........the method triggering the resolution (if any)
2665 iptr.............the INVOKE* instruction
2668 true.............everything ok
2669 false............an exception has been thrown
2671 *******************************************************************************/
2673 #if defined(ENABLE_VERIFIER)
2674 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2675 methodinfo *refmethod,
2676 typeinfo *instanceti,
2679 constant_FMIref *methodref;
2680 constant_classref *instanceref;
2685 methodref = ref->methodref;
2688 /* XXX clean this up */
2689 instanceref = IS_FMIREF_RESOLVED(methodref)
2690 ? class_get_self_classref(methodref->p.method->class)
2691 : methodref->p.classref;
2693 #ifdef RESOLVE_VERBOSE
2694 printf("resolve_constrain_unresolved_method_instance\n");
2695 printf(" rmethod: "); method_println(refmethod);
2696 printf(" mref : "); method_methodref_println(methodref);
2699 /* record subtype constraints for the instance type, if any */
2701 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2702 { /* XXX clean up */
2703 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2704 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2705 : CLASSREF_OR_CLASSINFO(refmethod->class);
2707 if (!typeinfo_init_class(tip, initclass))
2714 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2715 &(ref->instancetypes),tip,instanceref->name))
2720 #endif /* defined(ENABLE_VERIFIER) */
2723 /* resolve_constrain_unresolved_method_params *********************************
2725 Record subtype constraints for the non-instance arguments of a method call.
2728 jd...............current jitdata (for looking up variables)
2729 ref..............the unresolved_method structure of the call
2730 refmethod........the method triggering the resolution (if any)
2731 iptr.............the INVOKE* instruction
2734 true.............everything ok
2735 false............an exception has been thrown
2737 *******************************************************************************/
2739 #if defined(ENABLE_VERIFIER)
2740 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2741 unresolved_method *ref,
2742 methodinfo *refmethod,
2745 constant_FMIref *methodref;
2753 methodref = ref->methodref;
2755 md = methodref->parseddesc.md;
2757 assert(md->params != NULL);
2759 #ifdef RESOLVE_VERBOSE
2760 printf("resolve_constrain_unresolved_method_params\n");
2761 printf(" rmethod: "); method_println(refmethod);
2762 printf(" mref : "); method_methodref_println(methodref);
2765 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2767 /* record subtype constraints for the parameter types, if any */
2769 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2770 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2771 type = md->paramtypes[i+instancecount].type;
2774 assert(type == param->type);
2776 if (type == TYPE_ADR) {
2777 if (!ref->paramconstraints) {
2778 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2779 for (j=md->paramcount-1-instancecount; j>i; --j)
2780 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2782 assert(ref->paramconstraints);
2783 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2784 ref->paramconstraints + i,&(param->typeinfo),
2785 md->paramtypes[i+instancecount].classref->name))
2789 if (ref->paramconstraints)
2790 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2796 #endif /* ENABLE_VERIFIER */
2799 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2801 Record subtype constraints for the non-instance arguments of a method call.
2804 ref..............the unresolved_method structure of the call
2805 refmethod........the method triggering the resolution (if any)
2806 stack............TOS before the INVOKE instruction
2809 true.............everything ok
2810 false............an exception has been thrown
2812 *******************************************************************************/
2814 #if defined(ENABLE_VERIFIER)
2815 bool resolve_constrain_unresolved_method_params_stackbased(
2816 unresolved_method *ref,
2817 methodinfo *refmethod,
2818 typedescriptor *stack)
2820 constant_FMIref *methodref;
2821 typedescriptor *param;
2828 methodref = ref->methodref;
2830 md = methodref->parseddesc.md;
2832 assert(md->params != NULL);
2834 #ifdef RESOLVE_VERBOSE
2835 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2836 printf(" rmethod: "); method_println(refmethod);
2837 printf(" mref : "); method_methodref_println(methodref);
2840 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2842 /* record subtype constraints for the parameter types, if any */
2844 param = stack - (md->paramslots - 1 - instancecount);
2846 for (i = instancecount; i < md->paramcount; ++i) {
2847 type = md->paramtypes[i].type;
2849 assert(type == param->type);
2851 if (type == TYPE_ADR) {
2852 if (!ref->paramconstraints) {
2853 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2854 for (j = 0; j < i - instancecount; ++j)
2855 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2857 assert(ref->paramconstraints);
2858 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2859 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2860 md->paramtypes[i].classref->name))
2864 if (ref->paramconstraints)
2865 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2868 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2873 #endif /* ENABLE_VERIFIER */
2876 /******************************************************************************/
2877 /* FREEING MEMORY */
2878 /******************************************************************************/
2880 #ifdef ENABLE_VERIFIER
2881 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2884 classref_or_classinfo *p = list;
2886 /* this is silly. we *only* need to count the elements for MFREE */
2889 MFREE(list,classref_or_classinfo,(p - list));
2892 #endif /* ENABLE_VERIFIER */
2894 /* unresolved_class_free *******************************************************
2896 Free the memory used by an unresolved_class
2899 ref..............the unresolved_class
2901 *******************************************************************************/
2903 void unresolved_class_free(unresolved_class *ref)
2907 #ifdef ENABLE_VERIFIER
2908 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2910 FREE(ref,unresolved_class);
2913 /* unresolved_field_free *******************************************************
2915 Free the memory used by an unresolved_field
2918 ref..............the unresolved_field
2920 *******************************************************************************/
2922 void unresolved_field_free(unresolved_field *ref)
2926 #ifdef ENABLE_VERIFIER
2927 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2928 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2930 FREE(ref,unresolved_field);
2933 /* unresolved_method_free ******************************************************
2935 Free the memory used by an unresolved_method
2938 ref..............the unresolved_method
2940 *******************************************************************************/
2942 void unresolved_method_free(unresolved_method *ref)
2946 #ifdef ENABLE_VERIFIER
2947 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2948 if (ref->paramconstraints) {
2950 int count = ref->methodref->parseddesc.md->paramcount;
2952 for (i=0; i<count; ++i)
2953 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2954 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2957 FREE(ref,unresolved_method);
2960 /******************************************************************************/
2962 /******************************************************************************/
2964 #if !defined(NDEBUG)
2966 /* unresolved_subtype_set_debug_dump *******************************************
2968 Print debug info for unresolved_subtype_set to stream
2971 stset............the unresolved_subtype_set
2972 file.............the stream
2974 *******************************************************************************/
2976 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2978 classref_or_classinfo *p;
2980 if (SUBTYPESET_IS_EMPTY(*stset)) {
2981 fprintf(file," (empty)\n");
2984 p = stset->subtyperefs;
2985 for (;p->any; ++p) {
2986 if (IS_CLASSREF(*p)) {
2987 fprintf(file," ref: ");
2988 utf_fprint_printable_ascii(file,p->ref->name);
2991 fprintf(file," cls: ");
2992 utf_fprint_printable_ascii(file,p->cls->name);
2999 /* unresolved_class_debug_dump *************************************************
3001 Print debug info for unresolved_class to stream
3004 ref..............the unresolved_class
3005 file.............the stream
3007 *******************************************************************************/
3009 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3011 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3013 fprintf(file," referer : ");
3014 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3015 fprintf(file," refmethod : ");
3016 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3017 fprintf(file," refmethodd: ");
3018 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3019 fprintf(file," classname : ");
3020 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3021 fprintf(file," subtypeconstraints:\n");
3022 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3026 /* unresolved_field_debug_dump *************************************************
3028 Print debug info for unresolved_field to stream
3031 ref..............the unresolved_field
3032 file.............the stream
3034 *******************************************************************************/
3036 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3038 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3040 fprintf(file," referer : ");
3041 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3042 fprintf(file," refmethod : ");
3043 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3044 fprintf(file," refmethodd: ");
3045 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3046 fprintf(file," classname : ");
3047 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3048 fprintf(file," name : ");
3049 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3050 fprintf(file," descriptor: ");
3051 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3052 fprintf(file," parseddesc: ");
3053 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3054 fprintf(file," flags : %04x\n",ref->flags);
3055 fprintf(file," instancetypes:\n");
3056 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3057 fprintf(file," valueconstraints:\n");
3058 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3062 /* unresolved_method_debug_dump ************************************************
3064 Print debug info for unresolved_method to stream
3067 ref..............the unresolved_method
3068 file.............the stream
3070 *******************************************************************************/
3072 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3076 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3078 fprintf(file," referer : ");
3079 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3080 fprintf(file," refmethod : ");
3081 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3082 fprintf(file," refmethodd: ");
3083 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3084 fprintf(file," classname : ");
3085 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3086 fprintf(file," name : ");
3087 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3088 fprintf(file," descriptor: ");
3089 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3090 fprintf(file," parseddesc: ");
3091 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3092 fprintf(file," flags : %04x\n",ref->flags);
3093 fprintf(file," instancetypes:\n");
3094 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3095 fprintf(file," paramconstraints:\n");
3096 if (ref->paramconstraints) {
3097 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3098 fprintf(file," param %d:\n",i);
3099 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3103 fprintf(file," (empty)\n");
3107 #endif /* !defined(NDEBUG) */
3111 * These are local overrides for various environment variables in Emacs.
3112 * Please do not remove this and leave it at the end of the file, where
3113 * Emacs will automagically detect them.
3114 * ---------------------------------------------------------------------
3117 * indent-tabs-mode: t
3121 * vim:noexpandtab:sw=4:ts=4: