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 7983 2007-05-30 20:04:42Z twisti $
36 #include "mm/memory.h"
38 #include "vm/access.h"
39 #include "vm/exceptions.h"
40 #include "vm/global.h"
42 #include "vm/jit/jit.h"
43 #include "vm/jit/verify/typeinfo.h"
45 #include "vmcore/classcache.h"
46 #include "vmcore/descriptor.h"
47 #include "vmcore/linker.h"
48 #include "vmcore/loader.h"
49 #include "vmcore/options.h"
50 #include "vm/resolve.h"
53 /******************************************************************************/
55 /******************************************************************************/
57 /*#define RESOLVE_VERBOSE*/
59 /******************************************************************************/
60 /* CLASS RESOLUTION */
61 /******************************************************************************/
63 /* resolve_class_from_name *****************************************************
65 Resolve a symbolic class reference
68 referer..........the class containing the reference
69 refmethod........the method from which resolution was triggered
70 (may be NULL if not applicable)
71 classname........class name to resolve
72 mode.............mode of resolution:
73 resolveLazy...only resolve if it does not
74 require loading classes
75 resolveEager..load classes if necessary
76 checkaccess......if true, access rights to the class are checked
77 link.............if true, guarantee that the returned class, if any,
81 *result..........set to result of resolution, or to NULL if
82 the reference has not been resolved
83 In the case of an exception, *result is
84 guaranteed to be set to NULL.
87 true.............everything ok
88 (*result may still be NULL for resolveLazy)
89 false............an exception has been thrown
92 The returned class is *not* guaranteed to be linked!
93 (It is guaranteed to be loaded, though.)
95 *******************************************************************************/
97 bool resolve_class_from_name(classinfo *referer,
98 methodinfo *refmethod,
115 assert(mode == resolveLazy || mode == resolveEager);
119 #ifdef RESOLVE_VERBOSE
120 printf("resolve_class_from_name(");
121 utf_fprint_printable_ascii(stdout,referer->name);
122 printf(",%p,",(void*)referer->classloader);
123 utf_fprint_printable_ascii(stdout,classname);
124 printf(",%d,%d)\n",(int)checkaccess,(int)link);
127 /* lookup if this class has already been loaded */
129 cls = classcache_lookup(referer->classloader, classname);
131 #ifdef RESOLVE_VERBOSE
132 printf(" lookup result: %p\n",(void*)cls);
136 /* resolve array types */
138 if (classname->text[0] == '[') {
139 utf_ptr = classname->text + 1;
140 len = classname->blength - 1;
142 /* classname is an array type name */
150 /* the component type is a reference type */
151 /* resolve the component type */
152 if (!resolve_class_from_name(referer,refmethod,
153 utf_new(utf_ptr,len),
154 mode,checkaccess,link,&cls))
155 return false; /* exception */
157 assert(mode == resolveLazy);
158 return true; /* be lazy */
160 /* create the array class */
161 cls = class_array_of(cls,false);
163 return false; /* exception */
167 /* the class has not been loaded, yet */
168 if (mode == resolveLazy)
169 return true; /* be lazy */
172 #ifdef RESOLVE_VERBOSE
173 printf(" loading...\n");
178 if (!(cls = load_class_from_classloader(classname,
179 referer->classloader)))
180 return false; /* exception */
184 /* the class is now loaded */
186 assert(cls->state & CLASS_LOADED);
188 #ifdef RESOLVE_VERBOSE
189 printf(" checking access rights...\n");
192 /* check access rights of referer to refered class */
194 if (checkaccess && !access_is_accessible_class(referer,cls)) {
196 utf_bytes(cls->name) +
197 utf_bytes(referer->name) +
200 msg = MNEW(char, msglen);
202 strcpy(msg, "class is not accessible (");
203 utf_cat_classname(msg, cls->name);
204 strcat(msg, " from ");
205 utf_cat_classname(msg, referer->name);
208 u = utf_new_char(msg);
210 MFREE(msg, char, msglen);
212 exceptions_throw_illegalaccessexception(u);
214 return false; /* exception */
217 /* link the class if necessary */
219 if (!(cls->state & CLASS_LINKED))
220 if (!link_class(cls))
221 return false; /* exception */
223 assert(cls->state & CLASS_LINKED);
226 /* resolution succeeds */
227 #ifdef RESOLVE_VERBOSE
228 printf(" success.\n");
234 /* resolve_classref ************************************************************
236 Resolve a symbolic class reference
239 refmethod........the method from which resolution was triggered
240 (may be NULL if not applicable)
241 ref..............class reference
242 mode.............mode of resolution:
243 resolveLazy...only resolve if it does not
244 require loading classes
245 resolveEager..load classes if necessary
246 checkaccess......if true, access rights to the class are checked
247 link.............if true, guarantee that the returned class, if any,
251 *result..........set to result of resolution, or to NULL if
252 the reference has not been resolved
253 In the case of an exception, *result is
254 guaranteed to be set to NULL.
257 true.............everything ok
258 (*result may still be NULL for resolveLazy)
259 false............an exception has been thrown
261 *******************************************************************************/
263 bool resolve_classref(methodinfo *refmethod,
264 constant_classref *ref,
270 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
273 /* resolve_classref_or_classinfo ***********************************************
275 Resolve a symbolic class reference if necessary
277 NOTE: If given, refmethod->class is used as the referring class.
278 Otherwise, cls.ref->referer is used.
281 refmethod........the method from which resolution was triggered
282 (may be NULL if not applicable)
283 cls..............class reference or classinfo
284 mode.............mode of resolution:
285 resolveLazy...only resolve if it does not
286 require loading classes
287 resolveEager..load classes if necessary
288 checkaccess......if true, access rights to the class are checked
289 link.............if true, guarantee that the returned class, if any,
293 *result..........set to result of resolution, or to NULL if
294 the reference has not been resolved
295 In the case of an exception, *result is
296 guaranteed to be set to NULL.
299 true.............everything ok
300 (*result may still be NULL for resolveLazy)
301 false............an exception has been thrown
303 *******************************************************************************/
305 bool resolve_classref_or_classinfo(methodinfo *refmethod,
306 classref_or_classinfo cls,
316 assert(mode == resolveEager || mode == resolveLazy);
319 #ifdef RESOLVE_VERBOSE
320 printf("resolve_classref_or_classinfo(");
321 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
322 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
327 if (IS_CLASSREF(cls)) {
328 /* we must resolve this reference */
330 /* determine which class to use as the referer */
332 /* Common cases are refmethod == NULL or both referring classes */
333 /* being the same, so the referer usually is cls.ref->referer. */
334 /* There is one important case where it is not: When we do a */
335 /* deferred assignability check to a formal argument of a method, */
336 /* we must use refmethod->class (the caller's class) to resolve */
337 /* the type of the formal argument. */
339 referer = (refmethod) ? refmethod->class : cls.ref->referer;
341 if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
342 mode, checkaccess, link, &c))
343 goto return_exception;
346 /* cls has already been resolved */
348 assert(c->state & CLASS_LOADED);
350 assert(c || (mode == resolveLazy));
353 return true; /* be lazy */
356 assert(c->state & CLASS_LOADED);
359 if (!(c->state & CLASS_LINKED))
361 goto return_exception;
363 assert(c->state & CLASS_LINKED);
376 /* resolve_classref_or_classinfo_eager *****************************************
378 Resolve a symbolic class reference eagerly if necessary.
379 No attempt is made to link the class.
382 cls..............class reference or classinfo
383 checkaccess......if true, access rights to the class are checked
386 classinfo *......the resolved class
387 NULL.............an exception has been thrown
389 *******************************************************************************/
391 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
396 if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
403 /* resolve_class_from_typedesc *************************************************
405 Return a classinfo * for the given type descriptor
408 d................type descriptor
409 checkaccess......if true, access rights to the class are checked
410 link.............if true, guarantee that the returned class, if any,
413 *result..........set to result of resolution, or to NULL if
414 the reference has not been resolved
415 In the case of an exception, *result is
416 guaranteed to be set to NULL.
419 true.............everything ok
420 false............an exception has been thrown
423 This function always resolves eagerly.
425 *******************************************************************************/
427 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
436 #ifdef RESOLVE_VERBOSE
437 printf("resolve_class_from_typedesc(");
438 descriptor_debug_print_typedesc(stdout,d);
439 printf(",%i,%i)\n",(int)checkaccess,(int)link);
442 if (d->type == TYPE_ADR) {
443 /* a reference type */
445 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
446 resolveEager,checkaccess,link,&cls))
447 return false; /* exception */
450 /* a primitive type */
451 cls = primitivetype_table[d->decltype].class_primitive;
452 assert(cls->state & CLASS_LOADED);
453 if (!(cls->state & CLASS_LINKED))
454 if (!link_class(cls))
455 return false; /* exception */
458 assert(cls->state & CLASS_LOADED);
459 assert(!link || (cls->state & CLASS_LINKED));
461 #ifdef RESOLVE_VERBOSE
462 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
469 /******************************************************************************/
470 /* SUBTYPE SET CHECKS */
471 /******************************************************************************/
473 /* resolve_subtype_check *******************************************************
475 Resolve the given types lazily and perform a subtype check
478 refmethod........the method triggering the resolution
479 subtype..........checked to be a subtype of supertype
480 supertype........the super type to check agaings
481 mode.............mode of resolution:
482 resolveLazy...only resolve if it does not
483 require loading classes
484 resolveEager..load classes if necessary
485 error............which type of exception to throw if
486 the test fails. May be:
487 resolveLinkageError, or
488 resolveIllegalAccessError
489 IMPORTANT: If error==resolveIllegalAccessError,
490 then array types are not checked.
493 resolveSucceeded.....the check succeeded
494 resolveDeferred......the check could not be performed due to
495 unresolved types. (This can only happen for
496 mode == resolveLazy.)
497 resolveFailed........the check failed, an exception has been thrown.
500 The types are resolved first, so any
501 exception which may occurr during resolution may
502 be thrown by this function.
504 *******************************************************************************/
506 #if defined(ENABLE_VERIFIER)
507 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
508 classref_or_classinfo subtype,
509 classref_or_classinfo supertype,
522 assert(supertype.any);
523 assert(mode == resolveLazy || mode == resolveEager);
524 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
526 /* resolve the subtype */
528 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
529 /* the subclass could not be resolved. therefore we are sure that */
530 /* no instances of this subclass will ever exist -> skip this test */
531 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
532 exceptions_clear_exception();
533 return resolveSucceeded;
536 return resolveDeferred; /* be lazy */
538 assert(subclass->state & CLASS_LINKED);
540 /* do not check access to protected members of arrays */
542 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
543 return resolveSucceeded;
546 /* perform the subtype check */
548 typeinfo_init_classinfo(&subti,subclass);
550 r = typeinfo_is_assignable_to_class(&subti,supertype);
551 if (r == typecheck_FAIL)
552 return resolveFailed; /* failed, exception is already set */
554 if (r == typecheck_MAYBE) {
555 assert(IS_CLASSREF(supertype));
556 if (mode == resolveEager) {
557 if (!resolve_classref_or_classinfo(refmethod,supertype,
558 resolveEager,false,true,
561 return resolveFailed;
563 assert(supertype.cls);
567 return resolveDeferred; /* be lazy */
571 /* sub class relationship is false */
573 #if defined(RESOLVE_VERBOSE)
574 printf("SUBTYPE CHECK FAILED!\n");
578 utf_bytes(subclass->name) +
579 utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
582 msg = MNEW(char, msglen);
584 strcpy(msg, (error == resolveIllegalAccessError) ?
585 "illegal access to protected member (" :
586 "subtype constraint violated (");
588 utf_cat_classname(msg, subclass->name);
589 strcat(msg, " is not a subclass of ");
590 utf_cat_classname(msg, CLASSREF_OR_CLASSINFO_NAME(supertype));
593 u = utf_new_char(msg);
595 if (error == resolveIllegalAccessError)
596 exceptions_throw_illegalaccessexception(u);
598 exceptions_throw_linkageerror(msg, NULL);
600 /* ATTENTION: We probably need msg for
601 exceptions_throw_linkageerror. */
603 MFREE(msg, char, msglen);
605 return resolveFailed; /* exception */
610 return resolveSucceeded;
612 #endif /* defined(ENABLE_VERIFIER) */
614 /* resolve_lazy_subtype_checks *************************************************
616 Resolve the types to check lazily and perform subtype checks
619 refmethod........the method triggering the resolution
620 subtinfo.........the typeinfo containing the subtypes
621 supertype........the supertype to test againgst
622 mode.............mode of resolution:
623 resolveLazy...only resolve if it does not
624 require loading classes
625 resolveEager..load classes if necessary
626 error............which type of exception to throw if
627 the test fails. May be:
628 resolveLinkageError, or
629 resolveIllegalAccessError
630 IMPORTANT: If error==resolveIllegalAccessError,
631 then array types in the set are skipped.
634 resolveSucceeded.....the check succeeded
635 resolveDeferred......the check could not be performed due to
637 resolveFailed........the check failed, an exception has been thrown.
640 The references in the set are resolved first, so any
641 exception which may occurr during resolution may
642 be thrown by this function.
644 *******************************************************************************/
646 #if defined(ENABLE_VERIFIER)
647 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
649 classref_or_classinfo supertype,
654 resolve_result_t result;
658 assert(supertype.any);
659 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
661 /* returnAddresses are illegal here */
663 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
664 exceptions_throw_verifyerror(refmethod,
665 "Invalid use of returnAddress");
666 return resolveFailed;
669 /* uninitialized objects are illegal here */
671 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
672 exceptions_throw_verifyerror(refmethod,
673 "Invalid use of uninitialized object");
674 return resolveFailed;
677 /* the nulltype is always assignable */
679 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
680 return resolveSucceeded;
682 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
684 if (supertype.cls == class_java_lang_Object
685 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
686 && refmethod->class->classloader == NULL))
688 return resolveSucceeded;
691 if (subtinfo->merged) {
693 /* for a merged type we have to do a series of checks */
695 count = subtinfo->merged->count;
696 for (i=0; i<count; ++i) {
697 classref_or_classinfo c = subtinfo->merged->list[i];
698 if (subtinfo->dimension > 0) {
699 /* a merge of array types */
700 /* the merged list contains the possible _element_ types, */
701 /* so we have to create array types with these elements. */
702 if (IS_CLASSREF(c)) {
703 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
706 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
710 /* do the subtype check against the type c */
712 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
713 if (result != resolveSucceeded)
719 /* a single type, this is the common case, hopefully */
721 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
722 == CLASSREF_OR_CLASSINFO_NAME(supertype))
724 /* the class names are the same */
725 /* equality is guaranteed by the loading constraints */
726 return resolveSucceeded;
730 /* some other type name, try to perform the check lazily */
732 return resolve_subtype_check(refmethod,
733 subtinfo->typeclass,supertype,
740 return resolveSucceeded;
742 #endif /* defined(ENABLE_VERIFIER) */
744 /* resolve_and_check_subtype_set ***********************************************
746 Resolve the references in the given set and test subtype relationships
749 refmethod........the method triggering the resolution
750 ref..............a set of class/interface references
752 typeref..........the type to test against the set
753 mode.............mode of resolution:
754 resolveLazy...only resolve if it does not
755 require loading classes
756 resolveEager..load classes if necessary
757 error............which type of exception to throw if
758 the test fails. May be:
759 resolveLinkageError, or
760 resolveIllegalAccessError
761 IMPORTANT: If error==resolveIllegalAccessError,
762 then array types in the set are skipped.
765 resolveSucceeded.....the check succeeded
766 resolveDeferred......the check could not be performed due to
767 unresolved types. (This can only happen if
768 mode == resolveLazy.)
769 resolveFailed........the check failed, an exception has been thrown.
772 The references in the set are resolved first, so any
773 exception which may occurr during resolution may
774 be thrown by this function.
776 *******************************************************************************/
778 #if defined(ENABLE_VERIFIER)
779 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
780 unresolved_subtype_set *ref,
781 classref_or_classinfo typeref,
785 classref_or_classinfo *setp;
786 typecheck_result checkresult;
791 assert(mode == resolveLazy || mode == resolveEager);
792 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
794 #if defined(RESOLVE_VERBOSE)
795 printf("resolve_and_check_subtype_set:\n");
796 unresolved_subtype_set_debug_dump(ref, stdout);
797 if (IS_CLASSREF(typeref))
798 class_classref_println(typeref.ref);
800 class_println(typeref.cls);
803 setp = ref->subtyperefs;
805 /* an empty set of tests always succeeds */
806 if (!setp || !setp->any) {
807 return resolveSucceeded;
810 /* first resolve the type if necessary */
811 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
812 return resolveFailed; /* exception */
814 return resolveDeferred; /* be lazy */
816 assert(typeref.cls->state & CLASS_LINKED);
818 /* iterate over the set members */
820 for (; setp->any; ++setp) {
821 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
822 #if defined(RESOLVE_VERBOSE)
823 if (checkresult != resolveSucceeded)
824 printf("SUBTYPE CHECK FAILED!\n");
826 if (checkresult != resolveSucceeded)
831 return resolveSucceeded;
833 #endif /* defined(ENABLE_VERIFIER) */
835 /******************************************************************************/
836 /* CLASS RESOLUTION */
837 /******************************************************************************/
839 /* resolve_class ***************************************************************
841 Resolve an unresolved class reference. The class is also linked.
844 ref..............struct containing the reference
845 mode.............mode of resolution:
846 resolveLazy...only resolve if it does not
847 require loading classes
848 resolveEager..load classes if necessary
849 checkaccess......if true, access rights to the class are checked
852 *result..........set to the result of resolution, or to NULL if
853 the reference has not been resolved
854 In the case of an exception, *result is
855 guaranteed to be set to NULL.
858 true.............everything ok
859 (*result may still be NULL for resolveLazy)
860 false............an exception has been thrown
862 *******************************************************************************/
864 #ifdef ENABLE_VERIFIER
865 bool resolve_class(unresolved_class *ref,
871 resolve_result_t checkresult;
875 assert(mode == resolveLazy || mode == resolveEager);
879 #ifdef RESOLVE_VERBOSE
880 unresolved_class_debug_dump(ref,stdout);
883 /* first we must resolve the class */
884 if (!resolve_classref(ref->referermethod,
885 ref->classref,mode,checkaccess,true,&cls))
887 /* the class reference could not be resolved */
888 return false; /* exception */
891 return true; /* be lazy */
894 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
896 /* now we check the subtype constraints */
898 checkresult = resolve_and_check_subtype_set(ref->referermethod,
899 &(ref->subtypeconstraints),
900 CLASSREF_OR_CLASSINFO(cls),
902 resolveLinkageError);
903 if (checkresult != resolveSucceeded)
904 return (bool) checkresult;
910 #endif /* ENABLE_VERIFIER */
912 /* resolve_classref_eager ******************************************************
914 Resolve an unresolved class reference eagerly. The class is also linked and
915 access rights to the class are checked.
918 ref..............constant_classref to the class
921 classinfo * to the class, or
922 NULL if an exception has been thrown
924 *******************************************************************************/
926 classinfo * resolve_classref_eager(constant_classref *ref)
930 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
936 /* resolve_classref_eager_nonabstract ******************************************
938 Resolve an unresolved class reference eagerly. The class is also linked and
939 access rights to the class are checked. A check is performed that the class
943 ref..............constant_classref to the class
946 classinfo * to the class, or
947 NULL if an exception has been thrown
949 *******************************************************************************/
951 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
955 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
958 /* ensure that the class is not abstract */
960 if (c->flags & ACC_ABSTRACT) {
961 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
968 /* resolve_class_eager *********************************************************
970 Resolve an unresolved class reference eagerly. The class is also linked and
971 access rights to the class are checked.
974 ref..............struct containing the reference
977 classinfo * to the class, or
978 NULL if an exception has been thrown
980 *******************************************************************************/
982 #ifdef ENABLE_VERIFIER
983 classinfo * resolve_class_eager(unresolved_class *ref)
987 if (!resolve_class(ref,resolveEager,true,&c))
992 #endif /* ENABLE_VERIFIER */
994 /* resolve_class_eager_no_access_check *****************************************
996 Resolve an unresolved class reference eagerly. The class is also linked.
997 Access rights are _not_ checked.
1000 ref..............struct containing the reference
1003 classinfo * to the class, or
1004 NULL if an exception has been thrown
1006 *******************************************************************************/
1008 #ifdef ENABLE_VERIFIER
1009 classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
1013 if (!resolve_class(ref, resolveEager, false, &c))
1018 #endif /* ENABLE_VERIFIER */
1020 /******************************************************************************/
1021 /* FIELD RESOLUTION */
1022 /******************************************************************************/
1024 /* resolve_field_verifier_checks *******************************************
1026 Do the verifier checks necessary after field has been resolved.
1029 refmethod........the method containing the reference
1030 fieldref.........the field reference
1031 container........the class where the field was found
1032 fi...............the fieldinfo of the resolved field
1033 instanceti.......instance typeinfo, if available
1034 valueti..........value typeinfo, if available
1035 isstatic.........true if this is a *STATIC* instruction
1036 isput............true if this is a PUT* instruction
1039 resolveSucceeded....everything ok
1040 resolveDeferred.....tests could not be done, have been deferred
1041 resolveFailed.......exception has been thrown
1043 *******************************************************************************/
1045 #if defined(ENABLE_VERIFIER)
1046 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
1047 constant_FMIref *fieldref,
1048 classinfo *container,
1050 typeinfo *instanceti,
1055 classinfo *declarer;
1057 resolve_result_t result;
1058 constant_classref *fieldtyperef;
1068 /* get the classinfos and the field type */
1070 referer = refmethod->class;
1073 declarer = fi->class;
1075 assert(referer->state & CLASS_LINKED);
1077 fieldtyperef = fieldref->parseddesc.fd->classref;
1082 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1085 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1086 /* a static field is accessed via an instance, or vice versa */
1087 exceptions_throw_incompatibleclasschangeerror(declarer,
1088 (fi->flags & ACC_STATIC)
1089 ? "static field accessed via instance"
1090 : "instance field accessed without instance");
1092 return resolveFailed;
1095 /* check access rights */
1097 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1099 utf_bytes(declarer->name) +
1100 utf_bytes(fi->name) +
1101 utf_bytes(referer->name) +
1104 msg = MNEW(char, msglen);
1106 strcpy(msg, "field is not accessible (");
1107 utf_cat_classname(msg, declarer->name);
1109 utf_cat(msg, fi->name);
1110 strcat(msg, " from ");
1111 utf_cat_classname(msg, referer->name);
1114 u = utf_new_char(msg);
1116 MFREE(msg, char, msglen);
1118 exceptions_throw_illegalaccessexception(u);
1120 return resolveFailed; /* exception */
1123 /* for non-static methods we have to check the constraints on the */
1130 /* The instanceslot must contain a reference to a non-array type */
1132 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1133 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1134 return resolveFailed;
1136 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1137 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1138 return resolveFailed;
1141 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1143 /* The instruction writes a field in an uninitialized object. */
1144 /* This is only allowed when a field of an uninitialized 'this' object is */
1145 /* written inside an initialization method */
1147 classinfo *initclass;
1148 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1151 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1152 return resolveFailed;
1155 /* XXX check that class of field == refmethod->class */
1156 initclass = referer; /* XXX classrefs */
1157 assert(initclass->state & CLASS_LINKED);
1159 typeinfo_init_classinfo(&tinfo, initclass);
1163 insttip = instanceti;
1166 result = resolve_lazy_subtype_checks(refmethod,
1168 CLASSREF_OR_CLASSINFO(container),
1169 resolveLinkageError);
1170 if (result != resolveSucceeded)
1173 /* check protected access */
1175 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1177 result = resolve_lazy_subtype_checks(refmethod,
1179 CLASSREF_OR_CLASSINFO(referer),
1180 resolveIllegalAccessError);
1181 if (result != resolveSucceeded)
1187 /* for PUT* instructions we have to check the constraints on the value type */
1190 assert(fieldtyperef);
1192 /* check subtype constraints */
1193 result = resolve_lazy_subtype_checks(refmethod,
1195 CLASSREF_OR_CLASSINFO(fieldtyperef),
1196 resolveLinkageError);
1198 if (result != resolveSucceeded)
1202 /* impose loading constraint on field type */
1204 if (fi->type == TYPE_ADR) {
1205 assert(fieldtyperef);
1206 if (!classcache_add_constraint(declarer->classloader,
1207 referer->classloader,
1208 fieldtyperef->name))
1209 return resolveFailed;
1212 /* XXX impose loading constraint on instance? */
1215 return resolveSucceeded;
1217 #endif /* defined(ENABLE_VERIFIER) */
1219 /* resolve_field_lazy **********************************************************
1221 Resolve an unresolved field reference lazily
1223 NOTE: This function does NOT do any verification checks. In case of a
1224 successful resolution, you must call resolve_field_verifier_checks
1225 in order to perform the necessary checks!
1228 refmethod........the referer method
1229 fieldref.........the field reference
1232 resolveSucceeded.....the reference has been resolved
1233 resolveDeferred......the resolving could not be performed lazily
1234 resolveFailed........resolving failed, an exception has been thrown.
1236 *******************************************************************************/
1238 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1239 constant_FMIref *fieldref)
1242 classinfo *container;
1247 /* the class containing the reference */
1249 referer = refmethod->class;
1252 /* check if the field itself is already resolved */
1254 if (IS_FMIREF_RESOLVED(fieldref))
1255 return resolveSucceeded;
1257 /* first we must resolve the class containg the field */
1259 /* XXX can/may lazyResolving trigger linking? */
1261 if (!resolve_class_from_name(referer, refmethod,
1262 fieldref->p.classref->name, resolveLazy, true, true, &container))
1264 /* the class reference could not be resolved */
1265 return resolveFailed; /* exception */
1268 return resolveDeferred; /* be lazy */
1270 assert(container->state & CLASS_LINKED);
1272 /* now we must find the declaration of the field in `container`
1273 * or one of its superclasses */
1275 fi = class_resolvefield(container,
1276 fieldref->name, fieldref->descriptor,
1279 /* The field does not exist. But since we were called lazily, */
1280 /* this error must not be reported now. (It will be reported */
1281 /* if eager resolving of this field is ever tried.) */
1283 exceptions_clear_exception();
1284 return resolveDeferred; /* be lazy */
1287 /* cache the result of the resolution */
1289 fieldref->p.field = fi;
1292 return resolveSucceeded;
1295 /* resolve_field ***************************************************************
1297 Resolve an unresolved field reference
1300 ref..............struct containing the reference
1301 mode.............mode of resolution:
1302 resolveLazy...only resolve if it does not
1303 require loading classes
1304 resolveEager..load classes if necessary
1307 *result..........set to the result of resolution, or to NULL if
1308 the reference has not been resolved
1309 In the case of an exception, *result is
1310 guaranteed to be set to NULL.
1313 true.............everything ok
1314 (*result may still be NULL for resolveLazy)
1315 false............an exception has been thrown
1317 *******************************************************************************/
1319 bool resolve_field(unresolved_field *ref,
1320 resolve_mode_t mode,
1324 classinfo *container;
1325 classinfo *declarer;
1326 constant_classref *fieldtyperef;
1328 resolve_result_t checkresult;
1332 assert(mode == resolveLazy || mode == resolveEager);
1336 #ifdef RESOLVE_VERBOSE
1337 unresolved_field_debug_dump(ref,stdout);
1340 /* the class containing the reference */
1342 referer = ref->referermethod->class;
1345 /* check if the field itself is already resolved */
1346 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1347 fi = ref->fieldref->p.field;
1348 container = fi->class;
1349 goto resolved_the_field;
1352 /* first we must resolve the class containg the field */
1353 if (!resolve_class_from_name(referer,ref->referermethod,
1354 ref->fieldref->p.classref->name,mode,true,true,&container))
1356 /* the class reference could not be resolved */
1357 return false; /* exception */
1360 return true; /* be lazy */
1363 assert(container->state & CLASS_LOADED);
1364 assert(container->state & CLASS_LINKED);
1366 /* now we must find the declaration of the field in `container`
1367 * or one of its superclasses */
1369 #ifdef RESOLVE_VERBOSE
1370 printf(" resolving field in class...\n");
1373 fi = class_resolvefield(container,
1374 ref->fieldref->name,ref->fieldref->descriptor,
1377 if (mode == resolveLazy) {
1378 /* The field does not exist. But since we were called lazily, */
1379 /* this error must not be reported now. (It will be reported */
1380 /* if eager resolving of this field is ever tried.) */
1382 exceptions_clear_exception();
1383 return true; /* be lazy */
1386 return false; /* exception */
1389 /* cache the result of the resolution */
1390 ref->fieldref->p.field = fi;
1394 #ifdef ENABLE_VERIFIER
1395 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1396 /* that no missing parts of an instruction will be accessed. */
1398 checkresult = resolve_field_verifier_checks(
1403 NULL, /* instanceti, handled by constraints below */
1404 NULL, /* valueti, handled by constraints below */
1405 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1406 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1408 if (checkresult != resolveSucceeded)
1409 return (bool) checkresult;
1411 declarer = fi->class;
1413 assert(declarer->state & CLASS_LOADED);
1414 assert(declarer->state & CLASS_LINKED);
1416 /* for non-static accesses we have to check the constraints on the */
1419 if (!(ref->flags & RESOLVE_STATIC)) {
1420 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1421 &(ref->instancetypes),
1422 CLASSREF_OR_CLASSINFO(container),
1423 mode, resolveLinkageError);
1424 if (checkresult != resolveSucceeded)
1425 return (bool) checkresult;
1428 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1430 /* for PUT* instructions we have to check the constraints on the value type */
1431 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1432 assert(fieldtyperef);
1433 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1434 /* check subtype constraints */
1435 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1436 &(ref->valueconstraints),
1437 CLASSREF_OR_CLASSINFO(fieldtyperef),
1438 mode, resolveLinkageError);
1439 if (checkresult != resolveSucceeded)
1440 return (bool) checkresult;
1444 /* check protected access */
1445 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1446 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1447 &(ref->instancetypes),
1448 CLASSREF_OR_CLASSINFO(referer),
1450 resolveIllegalAccessError);
1451 if (checkresult != resolveSucceeded)
1452 return (bool) checkresult;
1456 #endif /* ENABLE_VERIFIER */
1464 /* resolve_field_eager *********************************************************
1466 Resolve an unresolved field reference eagerly.
1469 ref..............struct containing the reference
1472 fieldinfo * to the field, or
1473 NULL if an exception has been thrown
1475 *******************************************************************************/
1477 fieldinfo * resolve_field_eager(unresolved_field *ref)
1481 if (!resolve_field(ref,resolveEager,&fi))
1487 /******************************************************************************/
1488 /* METHOD RESOLUTION */
1489 /******************************************************************************/
1491 /* resolve_method_invokespecial_lookup *****************************************
1493 Do the special lookup for methods invoked by INVOKESPECIAL
1496 refmethod........the method containing the reference
1497 mi...............the methodinfo of the resolved method
1500 a methodinfo *...the result of the lookup,
1501 NULL.............an exception has been thrown
1503 *******************************************************************************/
1505 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1508 classinfo *declarer;
1514 /* get referer and declarer classes */
1516 referer = refmethod->class;
1519 declarer = mi->class;
1521 assert(referer->state & CLASS_LINKED);
1523 /* checks for INVOKESPECIAL: */
1524 /* for <init> and methods of the current class we don't need any */
1525 /* special checks. Otherwise we must verify that the called method */
1526 /* belongs to a super class of the current class */
1528 if ((referer != declarer) && (mi->name != utf_init)) {
1529 /* check that declarer is a super class of the current class */
1531 if (!class_issubclass(referer,declarer)) {
1532 exceptions_throw_verifyerror(refmethod,
1533 "INVOKESPECIAL calling non-super class method");
1537 /* if the referer has ACC_SUPER set, we must do the special */
1538 /* lookup starting with the direct super class of referer */
1540 if ((referer->flags & ACC_SUPER) != 0) {
1541 mi = class_resolvemethod(referer->super.cls,
1546 /* the spec calls for an AbstractMethodError in this case */
1548 exceptions_throw_abstractmethoderror();
1559 /* resolve_method_verifier_checks ******************************************
1561 Do the verifier checks necessary after a method has been resolved.
1564 refmethod........the method containing the reference
1565 methodref........the method reference
1566 mi...............the methodinfo of the resolved method
1567 invokestatic.....true if the method is invoked by INVOKESTATIC
1570 resolveSucceeded....everything ok
1571 resolveDeferred.....tests could not be done, have been deferred
1572 resolveFailed.......exception has been thrown
1574 *******************************************************************************/
1576 #if defined(ENABLE_VERIFIER)
1577 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1578 constant_FMIref *methodref,
1582 classinfo *declarer;
1592 #ifdef RESOLVE_VERBOSE
1593 printf("resolve_method_verifier_checks\n");
1594 printf(" flags: %02x\n",mi->flags);
1597 /* get the classinfos and the method descriptor */
1599 referer = refmethod->class;
1602 declarer = mi->class;
1607 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1608 /* a static method is accessed via an instance, or vice versa */
1609 exceptions_throw_incompatibleclasschangeerror(declarer,
1610 (mi->flags & ACC_STATIC)
1611 ? "static method called via instance"
1612 : "instance method called without instance");
1614 return resolveFailed;
1617 /* check access rights */
1619 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1620 /* XXX clean this up. this should be in exceptions.c */
1623 utf_bytes(declarer->name) +
1624 utf_bytes(mi->name) +
1625 utf_bytes(mi->descriptor) +
1626 utf_bytes(referer->name) +
1629 msg = MNEW(char, msglen);
1631 strcpy(msg, "method is not accessible (");
1632 utf_cat_classname(msg, declarer->name);
1634 utf_cat(msg, mi->name);
1635 utf_cat(msg, mi->descriptor);
1636 strcat(msg, " from ");
1637 utf_cat_classname(msg, referer->name);
1640 u = utf_new_char(msg);
1642 MFREE(msg, char, msglen);
1644 exceptions_throw_illegalaccessexception(u);
1646 return resolveFailed; /* exception */
1651 return resolveSucceeded;
1653 #endif /* defined(ENABLE_VERIFIER) */
1656 /* resolve_method_instance_type_checks *****************************************
1658 Check the instance type of a method invocation.
1661 refmethod........the method containing the reference
1662 mi...............the methodinfo of the resolved method
1663 instanceti.......typeinfo of the instance slot
1664 invokespecial....true if the method is invoked by INVOKESPECIAL
1667 resolveSucceeded....everything ok
1668 resolveDeferred.....tests could not be done, have been deferred
1669 resolveFailed.......exception has been thrown
1671 *******************************************************************************/
1673 #if defined(ENABLE_VERIFIER)
1674 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1676 typeinfo *instanceti,
1681 resolve_result_t result;
1683 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1684 { /* XXX clean up */
1685 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1686 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1687 : CLASSREF_OR_CLASSINFO(refmethod->class);
1689 if (!typeinfo_init_class(tip, initclass))
1696 result = resolve_lazy_subtype_checks(refmethod,
1698 CLASSREF_OR_CLASSINFO(mi->class),
1699 resolveLinkageError);
1700 if (result != resolveSucceeded)
1703 /* check protected access */
1705 /* XXX use other `declarer` than mi->class? */
1706 if (((mi->flags & ACC_PROTECTED) != 0)
1707 && !SAME_PACKAGE(mi->class, refmethod->class))
1709 result = resolve_lazy_subtype_checks(refmethod,
1711 CLASSREF_OR_CLASSINFO(refmethod->class),
1712 resolveIllegalAccessError);
1713 if (result != resolveSucceeded)
1719 return resolveSucceeded;
1721 #endif /* defined(ENABLE_VERIFIER) */
1724 /* resolve_method_param_type_checks ********************************************
1726 Check non-instance parameter types of a method invocation.
1729 jd...............jitdata of the method doing the call
1730 refmethod........the method containing the reference
1731 iptr.............the invoke instruction
1732 mi...............the methodinfo of the resolved method
1733 invokestatic.....true if the method is invoked by INVOKESTATIC
1736 resolveSucceeded....everything ok
1737 resolveDeferred.....tests could not be done, have been deferred
1738 resolveFailed.......exception has been thrown
1740 *******************************************************************************/
1742 #if defined(ENABLE_VERIFIER)
1743 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1744 methodinfo *refmethod,
1750 resolve_result_t result;
1752 typedesc *paramtypes;
1759 instancecount = (invokestatic) ? 0 : 1;
1761 /* check subtype constraints for TYPE_ADR parameters */
1763 md = mi->parseddesc;
1764 paramtypes = md->paramtypes;
1766 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1767 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1768 type = md->paramtypes[i+instancecount].type;
1771 assert(type == param->type);
1773 if (type == TYPE_ADR) {
1774 result = resolve_lazy_subtype_checks(refmethod,
1776 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1777 resolveLinkageError);
1778 if (result != resolveSucceeded)
1785 return resolveSucceeded;
1787 #endif /* defined(ENABLE_VERIFIER) */
1790 /* resolve_method_param_type_checks_stackbased *********************************
1792 Check non-instance parameter types of a method invocation.
1795 refmethod........the method containing the reference
1796 mi...............the methodinfo of the resolved method
1797 invokestatic.....true if the method is invoked by INVOKESTATIC
1798 stack............TOS before the INVOKE instruction
1801 resolveSucceeded....everything ok
1802 resolveDeferred.....tests could not be done, have been deferred
1803 resolveFailed.......exception has been thrown
1805 *******************************************************************************/
1807 #if defined(ENABLE_VERIFIER)
1808 resolve_result_t resolve_method_param_type_checks_stackbased(
1809 methodinfo *refmethod,
1812 typedescriptor *stack)
1814 typedescriptor *param;
1815 resolve_result_t result;
1817 typedesc *paramtypes;
1822 instancecount = (invokestatic) ? 0 : 1;
1824 /* check subtype constraints for TYPE_ADR parameters */
1826 md = mi->parseddesc;
1827 paramtypes = md->paramtypes;
1829 param = stack - (md->paramslots - 1 - instancecount);
1831 for (i = instancecount; i < md->paramcount; ++i) {
1832 type = md->paramtypes[i].type;
1834 assert(type == param->type);
1836 if (type == TYPE_ADR) {
1837 result = resolve_lazy_subtype_checks(refmethod,
1839 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1840 resolveLinkageError);
1841 if (result != resolveSucceeded)
1845 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1850 return resolveSucceeded;
1852 #endif /* defined(ENABLE_VERIFIER) */
1855 /* resolve_method_loading_constraints ******************************************
1857 Impose loading constraints on the parameters and return type of the
1861 referer..........the class refering to the method
1862 mi...............the method
1865 true................everything ok
1866 false...............an exception has been thrown
1868 *******************************************************************************/
1870 #if defined(ENABLE_VERIFIER)
1871 bool resolve_method_loading_constraints(classinfo *referer,
1875 typedesc *paramtypes;
1880 /* impose loading constraints on parameters (including instance) */
1882 md = mi->parseddesc;
1883 paramtypes = md->paramtypes;
1884 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1886 for (i = 0; i < md->paramcount; i++) {
1887 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1888 if (i < instancecount) {
1889 /* The type of the 'this' pointer is the class containing */
1890 /* the method definition. Since container is the same as, */
1891 /* or a subclass of declarer, we also constrain declarer */
1892 /* by transitivity of loading constraints. */
1893 name = mi->class->name;
1896 name = paramtypes[i].classref->name;
1899 /* The caller (referer) and the callee (container) must agree */
1900 /* on the types of the parameters. */
1901 if (!classcache_add_constraint(referer->classloader,
1902 mi->class->classloader, name))
1903 return false; /* exception */
1907 /* impose loading constraint onto return type */
1909 if (md->returntype.type == TYPE_ADR) {
1910 /* The caller (referer) and the callee (container) must agree */
1911 /* on the return type. */
1912 if (!classcache_add_constraint(referer->classloader,
1913 mi->class->classloader,
1914 md->returntype.classref->name))
1915 return false; /* exception */
1922 #endif /* defined(ENABLE_VERIFIER) */
1925 /* resolve_method_lazy *********************************************************
1927 Resolve an unresolved method reference lazily
1929 NOTE: This function does NOT do any verification checks. In case of a
1930 successful resolution, you must call resolve_method_verifier_checks
1931 in order to perform the necessary checks!
1934 refmethod........the referer method
1935 methodref........the method reference
1936 invokespecial....true if this is an INVOKESPECIAL instruction
1939 resolveSucceeded.....the reference has been resolved
1940 resolveDeferred......the resolving could not be performed lazily
1941 resolveFailed........resolving failed, an exception has been thrown.
1943 *******************************************************************************/
1945 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1946 constant_FMIref *methodref,
1950 classinfo *container;
1955 #ifdef RESOLVE_VERBOSE
1956 printf("resolve_method_lazy\n");
1959 /* the class containing the reference */
1961 referer = refmethod->class;
1964 /* check if the method itself is already resolved */
1966 if (IS_FMIREF_RESOLVED(methodref))
1967 return resolveSucceeded;
1969 /* first we must resolve the class containg the method */
1971 if (!resolve_class_from_name(referer, refmethod,
1972 methodref->p.classref->name, resolveLazy, true, true, &container))
1974 /* the class reference could not be resolved */
1975 return resolveFailed; /* exception */
1978 return resolveDeferred; /* be lazy */
1980 assert(container->state & CLASS_LINKED);
1982 /* now we must find the declaration of the method in `container`
1983 * or one of its superclasses */
1985 if (container->flags & ACC_INTERFACE) {
1986 mi = class_resolveinterfacemethod(container,
1988 methodref->descriptor,
1992 mi = class_resolveclassmethod(container,
1994 methodref->descriptor,
1999 /* The method does not exist. But since we were called lazily, */
2000 /* this error must not be reported now. (It will be reported */
2001 /* if eager resolving of this method is ever tried.) */
2003 exceptions_clear_exception();
2004 return resolveDeferred; /* be lazy */
2007 if (invokespecial) {
2008 mi = resolve_method_invokespecial_lookup(refmethod, mi);
2010 return resolveFailed; /* exception */
2013 /* have the method params already been parsed? no, do it. */
2015 if (!mi->parseddesc->params)
2016 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2017 return resolveFailed;
2019 /* cache the result of the resolution */
2021 methodref->p.method = mi;
2025 return resolveSucceeded;
2028 /* resolve_method **************************************************************
2030 Resolve an unresolved method reference
2033 ref..............struct containing the reference
2034 mode.............mode of resolution:
2035 resolveLazy...only resolve if it does not
2036 require loading classes
2037 resolveEager..load classes if necessary
2040 *result..........set to the result of resolution, or to NULL if
2041 the reference has not been resolved
2042 In the case of an exception, *result is
2043 guaranteed to be set to NULL.
2046 true.............everything ok
2047 (*result may still be NULL for resolveLazy)
2048 false............an exception has been thrown
2050 *******************************************************************************/
2052 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2055 classinfo *container;
2056 classinfo *declarer;
2058 typedesc *paramtypes;
2061 resolve_result_t checkresult;
2065 assert(mode == resolveLazy || mode == resolveEager);
2067 #ifdef RESOLVE_VERBOSE
2068 unresolved_method_debug_dump(ref,stdout);
2073 /* the class containing the reference */
2075 referer = ref->referermethod->class;
2078 /* check if the method itself is already resolved */
2080 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2081 mi = ref->methodref->p.method;
2082 container = mi->class;
2083 goto resolved_the_method;
2086 /* first we must resolve the class containing the method */
2088 if (!resolve_class_from_name(referer,ref->referermethod,
2089 ref->methodref->p.classref->name,mode,true,true,&container))
2091 /* the class reference could not be resolved */
2092 return false; /* exception */
2095 return true; /* be lazy */
2098 assert(container->state & CLASS_LINKED);
2100 /* now we must find the declaration of the method in `container`
2101 * or one of its superclasses */
2103 if (container->flags & ACC_INTERFACE) {
2104 mi = class_resolveinterfacemethod(container,
2105 ref->methodref->name,
2106 ref->methodref->descriptor,
2110 mi = class_resolveclassmethod(container,
2111 ref->methodref->name,
2112 ref->methodref->descriptor,
2117 if (mode == resolveLazy) {
2118 /* The method does not exist. But since we were called lazily, */
2119 /* this error must not be reported now. (It will be reported */
2120 /* if eager resolving of this method is ever tried.) */
2122 exceptions_clear_exception();
2123 return true; /* be lazy */
2126 return false; /* exception */ /* XXX set exceptionptr? */
2129 /* { the method reference has been resolved } */
2131 if (ref->flags & RESOLVE_SPECIAL) {
2132 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2134 return false; /* exception */
2137 /* have the method params already been parsed? no, do it. */
2139 if (!mi->parseddesc->params)
2140 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2143 /* cache the resolution */
2145 ref->methodref->p.method = mi;
2147 resolved_the_method:
2149 #ifdef ENABLE_VERIFIER
2152 checkresult = resolve_method_verifier_checks(
2156 (ref->flags & RESOLVE_STATIC));
2158 if (checkresult != resolveSucceeded)
2159 return (bool) checkresult;
2161 /* impose loading constraints on params and return type */
2163 if (!resolve_method_loading_constraints(referer, mi))
2166 declarer = mi->class;
2168 assert(referer->state & CLASS_LINKED);
2170 /* for non-static methods we have to check the constraints on the */
2173 if (!(ref->flags & RESOLVE_STATIC)) {
2174 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2175 &(ref->instancetypes),
2176 CLASSREF_OR_CLASSINFO(container),
2178 resolveLinkageError);
2179 if (checkresult != resolveSucceeded)
2180 return (bool) checkresult;
2187 /* check subtype constraints for TYPE_ADR parameters */
2189 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2190 paramtypes = mi->parseddesc->paramtypes;
2192 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2193 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2194 if (ref->paramconstraints) {
2195 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2196 ref->paramconstraints + i,
2197 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2199 resolveLinkageError);
2200 if (checkresult != resolveSucceeded)
2201 return (bool) checkresult;
2206 /* check protected access */
2208 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2210 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2211 &(ref->instancetypes),
2212 CLASSREF_OR_CLASSINFO(referer),
2214 resolveIllegalAccessError);
2215 if (checkresult != resolveSucceeded)
2216 return (bool) checkresult;
2219 #endif /* ENABLE_VERIFIER */
2226 /* resolve_method_eager ********************************************************
2228 Resolve an unresolved method reference eagerly.
2231 ref..............struct containing the reference
2234 methodinfo * to the method, or
2235 NULL if an exception has been thrown
2237 *******************************************************************************/
2239 methodinfo * resolve_method_eager(unresolved_method *ref)
2243 if (!resolve_method(ref,resolveEager,&mi))
2249 /******************************************************************************/
2250 /* CREATING THE DATA STRUCTURES */
2251 /******************************************************************************/
2253 #ifdef ENABLE_VERIFIER
2254 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2255 methodinfo *refmethod,
2256 unresolved_subtype_set *stset,
2258 utf *declaredclassname)
2266 #ifdef RESOLVE_VERBOSE
2267 printf("unresolved_subtype_set_from_typeinfo\n");
2268 #ifdef TYPEINFO_DEBUG
2269 typeinfo_print(stdout,tinfo,4);
2271 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2275 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2276 exceptions_throw_verifyerror(refmethod,
2277 "Invalid use of returnAddress");
2281 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2282 exceptions_throw_verifyerror(refmethod,
2283 "Invalid use of uninitialized object");
2287 /* the nulltype is always assignable */
2288 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2291 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2292 if (declaredclassname == utf_java_lang_Object
2293 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2298 if (tinfo->merged) {
2299 count = tinfo->merged->count;
2300 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2301 for (i=0; i<count; ++i) {
2302 classref_or_classinfo c = tinfo->merged->list[i];
2303 if (tinfo->dimension > 0) {
2304 /* a merge of array types */
2305 /* the merged list contains the possible _element_ types, */
2306 /* so we have to create array types with these elements. */
2307 if (IS_CLASSREF(c)) {
2308 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2311 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2314 stset->subtyperefs[i] = c;
2316 stset->subtyperefs[count].any = NULL; /* terminate */
2319 if ((IS_CLASSREF(tinfo->typeclass)
2320 ? tinfo->typeclass.ref->name
2321 : tinfo->typeclass.cls->name) == declaredclassname)
2323 /* the class names are the same */
2324 /* equality is guaranteed by the loading constraints */
2328 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2329 stset->subtyperefs[0] = tinfo->typeclass;
2330 stset->subtyperefs[1].any = NULL; /* terminate */
2337 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2340 #endif /* ENABLE_VERIFIER */
2342 /* create_unresolved_class *****************************************************
2344 Create an unresolved_class struct for the given class reference
2347 refmethod........the method triggering the resolution (if any)
2348 classref.........the class reference
2349 valuetype........value type to check against the resolved class
2350 may be NULL, if no typeinfo is available
2353 a pointer to a new unresolved_class struct, or
2354 NULL if an exception has been thrown
2356 *******************************************************************************/
2358 #ifdef ENABLE_VERIFIER
2359 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2360 constant_classref *classref,
2361 typeinfo *valuetype)
2363 unresolved_class *ref;
2365 #ifdef RESOLVE_VERBOSE
2366 printf("create_unresolved_class\n");
2367 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2369 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2370 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2372 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2375 ref = NEW(unresolved_class);
2376 ref->classref = classref;
2377 ref->referermethod = refmethod;
2380 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2381 &(ref->subtypeconstraints),valuetype,classref->name))
2385 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2390 #endif /* ENABLE_VERIFIER */
2392 /* resolve_create_unresolved_field *********************************************
2394 Create an unresolved_field struct for the given field access instruction
2397 referer..........the class containing the reference
2398 refmethod........the method triggering the resolution (if any)
2399 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2402 a pointer to a new unresolved_field struct, or
2403 NULL if an exception has been thrown
2405 *******************************************************************************/
2407 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2408 methodinfo *refmethod,
2411 unresolved_field *ref;
2412 constant_FMIref *fieldref = NULL;
2414 #ifdef RESOLVE_VERBOSE
2415 printf("create_unresolved_field\n");
2416 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2417 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2418 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2421 ref = NEW(unresolved_field);
2423 ref->referermethod = refmethod;
2424 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2426 switch (iptr->opc) {
2428 ref->flags |= RESOLVE_PUTFIELD;
2431 case ICMD_PUTFIELDCONST:
2432 ref->flags |= RESOLVE_PUTFIELD;
2435 case ICMD_PUTSTATIC:
2436 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2439 case ICMD_PUTSTATICCONST:
2440 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2446 case ICMD_GETSTATIC:
2447 ref->flags |= RESOLVE_STATIC;
2450 #if !defined(NDEBUG)
2456 fieldref = iptr->sx.s23.s3.fmiref;
2460 #ifdef RESOLVE_VERBOSE
2461 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2462 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2463 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2464 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2468 ref->fieldref = fieldref;
2473 /* resolve_constrain_unresolved_field ******************************************
2475 Record subtype constraints for a field access.
2478 ref..............the unresolved_field structure of the access
2479 referer..........the class containing the reference
2480 refmethod........the method triggering the resolution (if any)
2481 instanceti.......instance typeinfo, if available
2482 valueti..........value typeinfo, if available
2485 true.............everything ok
2486 false............an exception has been thrown
2488 *******************************************************************************/
2490 #if defined(ENABLE_VERIFIER)
2491 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2493 methodinfo *refmethod,
2494 typeinfo *instanceti,
2497 constant_FMIref *fieldref;
2504 fieldref = ref->fieldref;
2507 #ifdef RESOLVE_VERBOSE
2508 printf("constrain_unresolved_field\n");
2509 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2510 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2511 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2512 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2513 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2514 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2515 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2519 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2520 fd = fieldref->parseddesc.fd;
2523 /* record subtype constraints for the instance type, if any */
2527 /* The instanceslot must contain a reference to a non-array type */
2528 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2529 exceptions_throw_verifyerror(refmethod,
2530 "illegal instruction: field access on non-reference");
2533 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2534 exceptions_throw_verifyerror(refmethod,
2535 "illegal instruction: field access on array");
2539 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2540 TYPEINFO_IS_NEWOBJECT(*instanceti))
2542 /* The instruction writes a field in an uninitialized object. */
2543 /* This is only allowed when a field of an uninitialized 'this' object is */
2544 /* written inside an initialization method */
2546 classinfo *initclass;
2547 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2550 exceptions_throw_verifyerror(refmethod,
2551 "accessing field of uninitialized object");
2554 /* XXX check that class of field == refmethod->class */
2555 initclass = refmethod->class; /* XXX classrefs */
2556 assert(initclass->state & CLASS_LOADED);
2557 assert(initclass->state & CLASS_LINKED);
2559 typeinfo_init_classinfo(&tinfo, initclass);
2563 insttip = instanceti;
2565 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2566 &(ref->instancetypes), insttip,
2567 FIELDREF_CLASSNAME(fieldref)))
2571 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2574 /* record subtype constraints for the value type, if any */
2576 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2578 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2579 &(ref->valueconstraints), valueti,
2580 fieldref->parseddesc.fd->classref->name))
2584 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2589 #endif /* ENABLE_VERIFIER */
2591 /* resolve_create_unresolved_method ********************************************
2593 Create an unresolved_method struct for the given method invocation
2596 referer..........the class containing the reference
2597 refmethod........the method triggering the resolution (if any)
2598 iptr.............the INVOKE* instruction
2601 a pointer to a new unresolved_method struct, or
2602 NULL if an exception has been thrown
2604 *******************************************************************************/
2606 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2607 methodinfo *refmethod,
2608 constant_FMIref *methodref,
2612 unresolved_method *ref;
2616 #ifdef RESOLVE_VERBOSE
2617 printf("create_unresolved_method\n");
2618 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2619 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2620 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2621 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2622 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2625 /* allocate params if necessary */
2626 if (!methodref->parseddesc.md->params)
2627 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2628 (invokestatic) ? ACC_STATIC : ACC_NONE))
2631 /* create the data structure */
2632 ref = NEW(unresolved_method);
2633 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2634 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2635 ref->referermethod = refmethod;
2636 ref->methodref = methodref;
2637 ref->paramconstraints = NULL;
2638 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2644 /* resolve_constrain_unresolved_method_instance ********************************
2646 Record subtype constraints for the instance argument of a method call.
2649 ref..............the unresolved_method structure of the call
2650 referer..........the class containing the reference
2651 refmethod........the method triggering the resolution (if any)
2652 iptr.............the INVOKE* instruction
2655 true.............everything ok
2656 false............an exception has been thrown
2658 *******************************************************************************/
2660 #if defined(ENABLE_VERIFIER)
2661 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2662 methodinfo *refmethod,
2663 typeinfo *instanceti,
2666 constant_FMIref *methodref;
2667 constant_classref *instanceref;
2672 methodref = ref->methodref;
2675 /* XXX clean this up */
2676 instanceref = IS_FMIREF_RESOLVED(methodref)
2677 ? class_get_self_classref(methodref->p.method->class)
2678 : methodref->p.classref;
2680 #ifdef RESOLVE_VERBOSE
2681 printf("resolve_constrain_unresolved_method_instance\n");
2682 printf(" rmethod: "); method_println(refmethod);
2683 printf(" mref : "); method_methodref_println(methodref);
2686 /* record subtype constraints for the instance type, if any */
2688 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2689 { /* XXX clean up */
2690 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2691 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2692 : CLASSREF_OR_CLASSINFO(refmethod->class);
2694 if (!typeinfo_init_class(tip, initclass))
2701 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2702 &(ref->instancetypes),tip,instanceref->name))
2707 #endif /* defined(ENABLE_VERIFIER) */
2710 /* resolve_constrain_unresolved_method_params *********************************
2712 Record subtype constraints for the non-instance arguments of a method call.
2715 jd...............current jitdata (for looking up variables)
2716 ref..............the unresolved_method structure of the call
2717 refmethod........the method triggering the resolution (if any)
2718 iptr.............the INVOKE* instruction
2721 true.............everything ok
2722 false............an exception has been thrown
2724 *******************************************************************************/
2726 #if defined(ENABLE_VERIFIER)
2727 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2728 unresolved_method *ref,
2729 methodinfo *refmethod,
2732 constant_FMIref *methodref;
2740 methodref = ref->methodref;
2742 md = methodref->parseddesc.md;
2744 assert(md->params != NULL);
2746 #ifdef RESOLVE_VERBOSE
2747 printf("resolve_constrain_unresolved_method_params\n");
2748 printf(" rmethod: "); method_println(refmethod);
2749 printf(" mref : "); method_methodref_println(methodref);
2752 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2754 /* record subtype constraints for the parameter types, if any */
2756 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2757 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2758 type = md->paramtypes[i+instancecount].type;
2761 assert(type == param->type);
2763 if (type == TYPE_ADR) {
2764 if (!ref->paramconstraints) {
2765 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2766 for (j=md->paramcount-1-instancecount; j>i; --j)
2767 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2769 assert(ref->paramconstraints);
2770 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2771 ref->paramconstraints + i,&(param->typeinfo),
2772 md->paramtypes[i+instancecount].classref->name))
2776 if (ref->paramconstraints)
2777 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2783 #endif /* ENABLE_VERIFIER */
2786 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2788 Record subtype constraints for the non-instance arguments of a method call.
2791 ref..............the unresolved_method structure of the call
2792 refmethod........the method triggering the resolution (if any)
2793 stack............TOS before the INVOKE instruction
2796 true.............everything ok
2797 false............an exception has been thrown
2799 *******************************************************************************/
2801 #if defined(ENABLE_VERIFIER)
2802 bool resolve_constrain_unresolved_method_params_stackbased(
2803 unresolved_method *ref,
2804 methodinfo *refmethod,
2805 typedescriptor *stack)
2807 constant_FMIref *methodref;
2808 typedescriptor *param;
2815 methodref = ref->methodref;
2817 md = methodref->parseddesc.md;
2819 assert(md->params != NULL);
2821 #ifdef RESOLVE_VERBOSE
2822 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2823 printf(" rmethod: "); method_println(refmethod);
2824 printf(" mref : "); method_methodref_println(methodref);
2827 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2829 /* record subtype constraints for the parameter types, if any */
2831 param = stack - (md->paramslots - 1 - instancecount);
2833 for (i = instancecount; i < md->paramcount; ++i) {
2834 type = md->paramtypes[i].type;
2836 assert(type == param->type);
2838 if (type == TYPE_ADR) {
2839 if (!ref->paramconstraints) {
2840 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2841 for (j = 0; j < i - instancecount; ++j)
2842 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2844 assert(ref->paramconstraints);
2845 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2846 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2847 md->paramtypes[i].classref->name))
2851 if (ref->paramconstraints)
2852 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2855 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2860 #endif /* ENABLE_VERIFIER */
2863 /******************************************************************************/
2864 /* FREEING MEMORY */
2865 /******************************************************************************/
2867 #ifdef ENABLE_VERIFIER
2868 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2871 classref_or_classinfo *p = list;
2873 /* this is silly. we *only* need to count the elements for MFREE */
2876 MFREE(list,classref_or_classinfo,(p - list));
2879 #endif /* ENABLE_VERIFIER */
2881 /* unresolved_class_free *******************************************************
2883 Free the memory used by an unresolved_class
2886 ref..............the unresolved_class
2888 *******************************************************************************/
2890 void unresolved_class_free(unresolved_class *ref)
2894 #ifdef ENABLE_VERIFIER
2895 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2897 FREE(ref,unresolved_class);
2900 /* unresolved_field_free *******************************************************
2902 Free the memory used by an unresolved_field
2905 ref..............the unresolved_field
2907 *******************************************************************************/
2909 void unresolved_field_free(unresolved_field *ref)
2913 #ifdef ENABLE_VERIFIER
2914 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2915 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2917 FREE(ref,unresolved_field);
2920 /* unresolved_method_free ******************************************************
2922 Free the memory used by an unresolved_method
2925 ref..............the unresolved_method
2927 *******************************************************************************/
2929 void unresolved_method_free(unresolved_method *ref)
2933 #ifdef ENABLE_VERIFIER
2934 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2935 if (ref->paramconstraints) {
2937 int count = ref->methodref->parseddesc.md->paramcount;
2939 for (i=0; i<count; ++i)
2940 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2941 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2944 FREE(ref,unresolved_method);
2947 /******************************************************************************/
2949 /******************************************************************************/
2951 #if !defined(NDEBUG)
2953 /* unresolved_subtype_set_debug_dump *******************************************
2955 Print debug info for unresolved_subtype_set to stream
2958 stset............the unresolved_subtype_set
2959 file.............the stream
2961 *******************************************************************************/
2963 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2965 classref_or_classinfo *p;
2967 if (SUBTYPESET_IS_EMPTY(*stset)) {
2968 fprintf(file," (empty)\n");
2971 p = stset->subtyperefs;
2972 for (;p->any; ++p) {
2973 if (IS_CLASSREF(*p)) {
2974 fprintf(file," ref: ");
2975 utf_fprint_printable_ascii(file,p->ref->name);
2978 fprintf(file," cls: ");
2979 utf_fprint_printable_ascii(file,p->cls->name);
2986 /* unresolved_class_debug_dump *************************************************
2988 Print debug info for unresolved_class to stream
2991 ref..............the unresolved_class
2992 file.............the stream
2994 *******************************************************************************/
2996 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2998 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3000 fprintf(file," referer : ");
3001 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3002 fprintf(file," refmethod : ");
3003 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3004 fprintf(file," refmethodd: ");
3005 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3006 fprintf(file," classname : ");
3007 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3008 fprintf(file," subtypeconstraints:\n");
3009 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3013 /* unresolved_field_debug_dump *************************************************
3015 Print debug info for unresolved_field to stream
3018 ref..............the unresolved_field
3019 file.............the stream
3021 *******************************************************************************/
3023 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3025 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3027 fprintf(file," referer : ");
3028 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3029 fprintf(file," refmethod : ");
3030 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3031 fprintf(file," refmethodd: ");
3032 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3033 fprintf(file," classname : ");
3034 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3035 fprintf(file," name : ");
3036 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3037 fprintf(file," descriptor: ");
3038 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3039 fprintf(file," parseddesc: ");
3040 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3041 fprintf(file," flags : %04x\n",ref->flags);
3042 fprintf(file," instancetypes:\n");
3043 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3044 fprintf(file," valueconstraints:\n");
3045 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3049 /* unresolved_method_debug_dump ************************************************
3051 Print debug info for unresolved_method to stream
3054 ref..............the unresolved_method
3055 file.............the stream
3057 *******************************************************************************/
3059 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3063 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3065 fprintf(file," referer : ");
3066 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3067 fprintf(file," refmethod : ");
3068 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3069 fprintf(file," refmethodd: ");
3070 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3071 fprintf(file," classname : ");
3072 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3073 fprintf(file," name : ");
3074 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3075 fprintf(file," descriptor: ");
3076 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3077 fprintf(file," parseddesc: ");
3078 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3079 fprintf(file," flags : %04x\n",ref->flags);
3080 fprintf(file," instancetypes:\n");
3081 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3082 fprintf(file," paramconstraints:\n");
3083 if (ref->paramconstraints) {
3084 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3085 fprintf(file," param %d:\n",i);
3086 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3090 fprintf(file," (empty)\n");
3094 #endif /* !defined(NDEBUG) */
3098 * These are local overrides for various environment variables in Emacs.
3099 * Please do not remove this and leave it at the end of the file, where
3100 * Emacs will automagically detect them.
3101 * ---------------------------------------------------------------------
3104 * indent-tabs-mode: t
3108 * vim:noexpandtab:sw=4:ts=4: