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 8060 2007-06-10 20:00:40Z twisti $
36 #include "mm/memory.h"
38 #include "vm/access.h"
39 #include "vm/exceptions.h"
40 #include "vm/global.h"
41 #include "vm/resolve.h"
43 #include "vm/jit/jit.h"
44 #include "vm/jit/verify/typeinfo.h"
46 #include "vmcore/classcache.h"
47 #include "vmcore/descriptor.h"
48 #include "vmcore/linker.h"
49 #include "vmcore/loader.h"
50 #include "vmcore/options.h"
51 #include "vmcore/primitive.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");
179 if (!(cls = load_class_from_classloader(classname,
180 referer->classloader)))
181 return false; /* exception */
185 /* the class is now loaded */
187 assert(cls->state & CLASS_LOADED);
189 #ifdef RESOLVE_VERBOSE
190 printf(" checking access rights...\n");
193 /* check access rights of referer to refered class */
195 if (checkaccess && !access_is_accessible_class(referer,cls)) {
197 utf_bytes(cls->name) +
198 utf_bytes(referer->name) +
201 msg = MNEW(char, msglen);
203 strcpy(msg, "class is not accessible (");
204 utf_cat_classname(msg, cls->name);
205 strcat(msg, " from ");
206 utf_cat_classname(msg, referer->name);
209 u = utf_new_char(msg);
211 MFREE(msg, char, msglen);
213 exceptions_throw_illegalaccessexception(u);
215 return false; /* exception */
218 /* link the class if necessary */
220 if (!(cls->state & CLASS_LINKED))
221 if (!link_class(cls))
222 return false; /* exception */
224 assert(cls->state & CLASS_LINKED);
227 /* resolution succeeds */
228 #ifdef RESOLVE_VERBOSE
229 printf(" success.\n");
235 /* resolve_classref ************************************************************
237 Resolve a symbolic class reference
240 refmethod........the method from which resolution was triggered
241 (may be NULL if not applicable)
242 ref..............class reference
243 mode.............mode of resolution:
244 resolveLazy...only resolve if it does not
245 require loading classes
246 resolveEager..load classes if necessary
247 checkaccess......if true, access rights to the class are checked
248 link.............if true, guarantee that the returned class, if any,
252 *result..........set to result of resolution, or to NULL if
253 the reference has not been resolved
254 In the case of an exception, *result is
255 guaranteed to be set to NULL.
258 true.............everything ok
259 (*result may still be NULL for resolveLazy)
260 false............an exception has been thrown
262 *******************************************************************************/
264 bool resolve_classref(methodinfo *refmethod,
265 constant_classref *ref,
271 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
274 /* resolve_classref_or_classinfo ***********************************************
276 Resolve a symbolic class reference if necessary
278 NOTE: If given, refmethod->class is used as the referring class.
279 Otherwise, cls.ref->referer is used.
282 refmethod........the method from which resolution was triggered
283 (may be NULL if not applicable)
284 cls..............class reference or classinfo
285 mode.............mode of resolution:
286 resolveLazy...only resolve if it does not
287 require loading classes
288 resolveEager..load classes if necessary
289 checkaccess......if true, access rights to the class are checked
290 link.............if true, guarantee that the returned class, if any,
294 *result..........set to result of resolution, or to NULL if
295 the reference has not been resolved
296 In the case of an exception, *result is
297 guaranteed to be set to NULL.
300 true.............everything ok
301 (*result may still be NULL for resolveLazy)
302 false............an exception has been thrown
304 *******************************************************************************/
306 bool resolve_classref_or_classinfo(methodinfo *refmethod,
307 classref_or_classinfo cls,
317 assert(mode == resolveEager || mode == resolveLazy);
320 #ifdef RESOLVE_VERBOSE
321 printf("resolve_classref_or_classinfo(");
322 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
323 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
328 if (IS_CLASSREF(cls)) {
329 /* we must resolve this reference */
331 /* determine which class to use as the referer */
333 /* Common cases are refmethod == NULL or both referring classes */
334 /* being the same, so the referer usually is cls.ref->referer. */
335 /* There is one important case where it is not: When we do a */
336 /* deferred assignability check to a formal argument of a method, */
337 /* we must use refmethod->class (the caller's class) to resolve */
338 /* the type of the formal argument. */
340 referer = (refmethod) ? refmethod->class : cls.ref->referer;
342 if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
343 mode, checkaccess, link, &c))
344 goto return_exception;
347 /* cls has already been resolved */
349 assert(c->state & CLASS_LOADED);
351 assert(c || (mode == resolveLazy));
354 return true; /* be lazy */
357 assert(c->state & CLASS_LOADED);
360 if (!(c->state & CLASS_LINKED))
362 goto return_exception;
364 assert(c->state & CLASS_LINKED);
377 /* resolve_classref_or_classinfo_eager *****************************************
379 Resolve a symbolic class reference eagerly if necessary.
380 No attempt is made to link the class.
383 cls..............class reference or classinfo
384 checkaccess......if true, access rights to the class are checked
387 classinfo *......the resolved class
388 NULL.............an exception has been thrown
390 *******************************************************************************/
392 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
397 if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
404 /* resolve_class_from_typedesc *************************************************
406 Return a classinfo * for the given type descriptor
409 d................type descriptor
410 checkaccess......if true, access rights to the class are checked
411 link.............if true, guarantee that the returned class, if any,
414 *result..........set to result of resolution, or to NULL if
415 the reference has not been resolved
416 In the case of an exception, *result is
417 guaranteed to be set to NULL.
420 true.............everything ok
421 false............an exception has been thrown
424 This function always resolves eagerly.
426 *******************************************************************************/
428 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
437 #ifdef RESOLVE_VERBOSE
438 printf("resolve_class_from_typedesc(");
439 descriptor_debug_print_typedesc(stdout,d);
440 printf(",%i,%i)\n",(int)checkaccess,(int)link);
443 if (d->type == TYPE_ADR) {
444 /* a reference type */
446 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
447 resolveEager,checkaccess,link,&cls))
448 return false; /* exception */
451 /* a primitive type */
453 cls = primitive_class_get_by_type(d->decltype);
455 assert(cls->state & CLASS_LOADED);
457 if (!(cls->state & CLASS_LINKED))
458 if (!link_class(cls))
459 return false; /* exception */
463 assert(cls->state & CLASS_LOADED);
464 assert(!link || (cls->state & CLASS_LINKED));
466 #ifdef RESOLVE_VERBOSE
467 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
474 /******************************************************************************/
475 /* SUBTYPE SET CHECKS */
476 /******************************************************************************/
478 /* resolve_subtype_check *******************************************************
480 Resolve the given types lazily and perform a subtype check
483 refmethod........the method triggering the resolution
484 subtype..........checked to be a subtype of supertype
485 supertype........the super type to check agaings
486 mode.............mode of resolution:
487 resolveLazy...only resolve if it does not
488 require loading classes
489 resolveEager..load classes if necessary
490 error............which type of exception to throw if
491 the test fails. May be:
492 resolveLinkageError, or
493 resolveIllegalAccessError
494 IMPORTANT: If error==resolveIllegalAccessError,
495 then array types are not checked.
498 resolveSucceeded.....the check succeeded
499 resolveDeferred......the check could not be performed due to
500 unresolved types. (This can only happen for
501 mode == resolveLazy.)
502 resolveFailed........the check failed, an exception has been thrown.
505 The types are resolved first, so any
506 exception which may occurr during resolution may
507 be thrown by this function.
509 *******************************************************************************/
511 #if defined(ENABLE_VERIFIER)
512 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
513 classref_or_classinfo subtype,
514 classref_or_classinfo supertype,
527 assert(supertype.any);
528 assert(mode == resolveLazy || mode == resolveEager);
529 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
531 /* resolve the subtype */
533 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
534 /* the subclass could not be resolved. therefore we are sure that */
535 /* no instances of this subclass will ever exist -> skip this test */
536 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
537 exceptions_clear_exception();
538 return resolveSucceeded;
541 return resolveDeferred; /* be lazy */
543 assert(subclass->state & CLASS_LINKED);
545 /* do not check access to protected members of arrays */
547 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
548 return resolveSucceeded;
551 /* perform the subtype check */
553 typeinfo_init_classinfo(&subti,subclass);
555 r = typeinfo_is_assignable_to_class(&subti,supertype);
556 if (r == typecheck_FAIL)
557 return resolveFailed; /* failed, exception is already set */
559 if (r == typecheck_MAYBE) {
560 assert(IS_CLASSREF(supertype));
561 if (mode == resolveEager) {
562 if (!resolve_classref_or_classinfo(refmethod,supertype,
563 resolveEager,false,true,
566 return resolveFailed;
568 assert(supertype.cls);
572 return resolveDeferred; /* be lazy */
576 /* sub class relationship is false */
578 #if defined(RESOLVE_VERBOSE)
579 printf("SUBTYPE CHECK FAILED!\n");
583 utf_bytes(subclass->name) +
584 utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
587 msg = MNEW(char, msglen);
589 strcpy(msg, (error == resolveIllegalAccessError) ?
590 "illegal access to protected member (" :
591 "subtype constraint violated (");
593 utf_cat_classname(msg, subclass->name);
594 strcat(msg, " is not a subclass of ");
595 utf_cat_classname(msg, CLASSREF_OR_CLASSINFO_NAME(supertype));
598 u = utf_new_char(msg);
600 if (error == resolveIllegalAccessError)
601 exceptions_throw_illegalaccessexception(u);
603 exceptions_throw_linkageerror(msg, NULL);
605 /* ATTENTION: We probably need msg for
606 exceptions_throw_linkageerror. */
608 MFREE(msg, char, msglen);
610 return resolveFailed; /* exception */
615 return resolveSucceeded;
617 #endif /* defined(ENABLE_VERIFIER) */
619 /* resolve_lazy_subtype_checks *************************************************
621 Resolve the types to check lazily and perform subtype checks
624 refmethod........the method triggering the resolution
625 subtinfo.........the typeinfo containing the subtypes
626 supertype........the supertype to test againgst
627 mode.............mode of resolution:
628 resolveLazy...only resolve if it does not
629 require loading classes
630 resolveEager..load classes if necessary
631 error............which type of exception to throw if
632 the test fails. May be:
633 resolveLinkageError, or
634 resolveIllegalAccessError
635 IMPORTANT: If error==resolveIllegalAccessError,
636 then array types in the set are skipped.
639 resolveSucceeded.....the check succeeded
640 resolveDeferred......the check could not be performed due to
642 resolveFailed........the check failed, an exception has been thrown.
645 The references in the set are resolved first, so any
646 exception which may occurr during resolution may
647 be thrown by this function.
649 *******************************************************************************/
651 #if defined(ENABLE_VERIFIER)
652 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
654 classref_or_classinfo supertype,
659 resolve_result_t result;
663 assert(supertype.any);
664 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
666 /* returnAddresses are illegal here */
668 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
669 exceptions_throw_verifyerror(refmethod,
670 "Invalid use of returnAddress");
671 return resolveFailed;
674 /* uninitialized objects are illegal here */
676 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
677 exceptions_throw_verifyerror(refmethod,
678 "Invalid use of uninitialized object");
679 return resolveFailed;
682 /* the nulltype is always assignable */
684 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
685 return resolveSucceeded;
687 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
689 if (supertype.cls == class_java_lang_Object
690 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
691 && refmethod->class->classloader == NULL))
693 return resolveSucceeded;
696 if (subtinfo->merged) {
698 /* for a merged type we have to do a series of checks */
700 count = subtinfo->merged->count;
701 for (i=0; i<count; ++i) {
702 classref_or_classinfo c = subtinfo->merged->list[i];
703 if (subtinfo->dimension > 0) {
704 /* a merge of array types */
705 /* the merged list contains the possible _element_ types, */
706 /* so we have to create array types with these elements. */
707 if (IS_CLASSREF(c)) {
708 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
711 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
715 /* do the subtype check against the type c */
717 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
718 if (result != resolveSucceeded)
724 /* a single type, this is the common case, hopefully */
726 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
727 == CLASSREF_OR_CLASSINFO_NAME(supertype))
729 /* the class names are the same */
730 /* equality is guaranteed by the loading constraints */
731 return resolveSucceeded;
735 /* some other type name, try to perform the check lazily */
737 return resolve_subtype_check(refmethod,
738 subtinfo->typeclass,supertype,
745 return resolveSucceeded;
747 #endif /* defined(ENABLE_VERIFIER) */
749 /* resolve_and_check_subtype_set ***********************************************
751 Resolve the references in the given set and test subtype relationships
754 refmethod........the method triggering the resolution
755 ref..............a set of class/interface references
757 typeref..........the type to test against the set
758 mode.............mode of resolution:
759 resolveLazy...only resolve if it does not
760 require loading classes
761 resolveEager..load classes if necessary
762 error............which type of exception to throw if
763 the test fails. May be:
764 resolveLinkageError, or
765 resolveIllegalAccessError
766 IMPORTANT: If error==resolveIllegalAccessError,
767 then array types in the set are skipped.
770 resolveSucceeded.....the check succeeded
771 resolveDeferred......the check could not be performed due to
772 unresolved types. (This can only happen if
773 mode == resolveLazy.)
774 resolveFailed........the check failed, an exception has been thrown.
777 The references in the set are resolved first, so any
778 exception which may occurr during resolution may
779 be thrown by this function.
781 *******************************************************************************/
783 #if defined(ENABLE_VERIFIER)
784 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
785 unresolved_subtype_set *ref,
786 classref_or_classinfo typeref,
790 classref_or_classinfo *setp;
791 typecheck_result checkresult;
796 assert(mode == resolveLazy || mode == resolveEager);
797 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
799 #if defined(RESOLVE_VERBOSE)
800 printf("resolve_and_check_subtype_set:\n");
801 unresolved_subtype_set_debug_dump(ref, stdout);
802 if (IS_CLASSREF(typeref))
803 class_classref_println(typeref.ref);
805 class_println(typeref.cls);
808 setp = ref->subtyperefs;
810 /* an empty set of tests always succeeds */
811 if (!setp || !setp->any) {
812 return resolveSucceeded;
815 /* first resolve the type if necessary */
816 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
817 return resolveFailed; /* exception */
819 return resolveDeferred; /* be lazy */
821 assert(typeref.cls->state & CLASS_LINKED);
823 /* iterate over the set members */
825 for (; setp->any; ++setp) {
826 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
827 #if defined(RESOLVE_VERBOSE)
828 if (checkresult != resolveSucceeded)
829 printf("SUBTYPE CHECK FAILED!\n");
831 if (checkresult != resolveSucceeded)
836 return resolveSucceeded;
838 #endif /* defined(ENABLE_VERIFIER) */
840 /******************************************************************************/
841 /* CLASS RESOLUTION */
842 /******************************************************************************/
844 /* resolve_class ***************************************************************
846 Resolve an unresolved class reference. The class is also linked.
849 ref..............struct containing the reference
850 mode.............mode of resolution:
851 resolveLazy...only resolve if it does not
852 require loading classes
853 resolveEager..load classes if necessary
854 checkaccess......if true, access rights to the class are checked
857 *result..........set to the result of resolution, or to NULL if
858 the reference has not been resolved
859 In the case of an exception, *result is
860 guaranteed to be set to NULL.
863 true.............everything ok
864 (*result may still be NULL for resolveLazy)
865 false............an exception has been thrown
867 *******************************************************************************/
869 #ifdef ENABLE_VERIFIER
870 bool resolve_class(unresolved_class *ref,
876 resolve_result_t checkresult;
880 assert(mode == resolveLazy || mode == resolveEager);
884 #ifdef RESOLVE_VERBOSE
885 unresolved_class_debug_dump(ref,stdout);
888 /* first we must resolve the class */
889 if (!resolve_classref(ref->referermethod,
890 ref->classref,mode,checkaccess,true,&cls))
892 /* the class reference could not be resolved */
893 return false; /* exception */
896 return true; /* be lazy */
899 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
901 /* now we check the subtype constraints */
903 checkresult = resolve_and_check_subtype_set(ref->referermethod,
904 &(ref->subtypeconstraints),
905 CLASSREF_OR_CLASSINFO(cls),
907 resolveLinkageError);
908 if (checkresult != resolveSucceeded)
909 return (bool) checkresult;
915 #endif /* ENABLE_VERIFIER */
917 /* resolve_classref_eager ******************************************************
919 Resolve an unresolved class reference eagerly. The class is also linked and
920 access rights to the class are checked.
923 ref..............constant_classref to the class
926 classinfo * to the class, or
927 NULL if an exception has been thrown
929 *******************************************************************************/
931 classinfo * resolve_classref_eager(constant_classref *ref)
935 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
941 /* resolve_classref_eager_nonabstract ******************************************
943 Resolve an unresolved class reference eagerly. The class is also linked and
944 access rights to the class are checked. A check is performed that the class
948 ref..............constant_classref to the class
951 classinfo * to the class, or
952 NULL if an exception has been thrown
954 *******************************************************************************/
956 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
960 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
963 /* ensure that the class is not abstract */
965 if (c->flags & ACC_ABSTRACT) {
966 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
973 /* resolve_class_eager *********************************************************
975 Resolve an unresolved class reference eagerly. The class is also linked and
976 access rights to the class are checked.
979 ref..............struct containing the reference
982 classinfo * to the class, or
983 NULL if an exception has been thrown
985 *******************************************************************************/
987 #ifdef ENABLE_VERIFIER
988 classinfo * resolve_class_eager(unresolved_class *ref)
992 if (!resolve_class(ref,resolveEager,true,&c))
997 #endif /* ENABLE_VERIFIER */
999 /* resolve_class_eager_no_access_check *****************************************
1001 Resolve an unresolved class reference eagerly. The class is also linked.
1002 Access rights are _not_ checked.
1005 ref..............struct containing the reference
1008 classinfo * to the class, or
1009 NULL if an exception has been thrown
1011 *******************************************************************************/
1013 #ifdef ENABLE_VERIFIER
1014 classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
1018 if (!resolve_class(ref, resolveEager, false, &c))
1023 #endif /* ENABLE_VERIFIER */
1025 /******************************************************************************/
1026 /* FIELD RESOLUTION */
1027 /******************************************************************************/
1029 /* resolve_field_verifier_checks *******************************************
1031 Do the verifier checks necessary after field has been resolved.
1034 refmethod........the method containing the reference
1035 fieldref.........the field reference
1036 container........the class where the field was found
1037 fi...............the fieldinfo of the resolved field
1038 instanceti.......instance typeinfo, if available
1039 valueti..........value typeinfo, if available
1040 isstatic.........true if this is a *STATIC* instruction
1041 isput............true if this is a PUT* instruction
1044 resolveSucceeded....everything ok
1045 resolveDeferred.....tests could not be done, have been deferred
1046 resolveFailed.......exception has been thrown
1048 *******************************************************************************/
1050 #if defined(ENABLE_VERIFIER)
1051 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
1052 constant_FMIref *fieldref,
1053 classinfo *container,
1055 typeinfo *instanceti,
1060 classinfo *declarer;
1062 resolve_result_t result;
1063 constant_classref *fieldtyperef;
1073 /* get the classinfos and the field type */
1075 referer = refmethod->class;
1078 declarer = fi->class;
1080 assert(referer->state & CLASS_LINKED);
1082 fieldtyperef = fieldref->parseddesc.fd->classref;
1087 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1090 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1091 /* a static field is accessed via an instance, or vice versa */
1092 exceptions_throw_incompatibleclasschangeerror(declarer,
1093 (fi->flags & ACC_STATIC)
1094 ? "static field accessed via instance"
1095 : "instance field accessed without instance");
1097 return resolveFailed;
1100 /* check access rights */
1102 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1104 utf_bytes(declarer->name) +
1105 utf_bytes(fi->name) +
1106 utf_bytes(referer->name) +
1109 msg = MNEW(char, msglen);
1111 strcpy(msg, "field is not accessible (");
1112 utf_cat_classname(msg, declarer->name);
1114 utf_cat(msg, fi->name);
1115 strcat(msg, " from ");
1116 utf_cat_classname(msg, referer->name);
1119 u = utf_new_char(msg);
1121 MFREE(msg, char, msglen);
1123 exceptions_throw_illegalaccessexception(u);
1125 return resolveFailed; /* exception */
1128 /* for non-static methods we have to check the constraints on the */
1135 /* The instanceslot must contain a reference to a non-array type */
1137 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1138 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1139 return resolveFailed;
1141 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1142 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1143 return resolveFailed;
1146 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1148 /* The instruction writes a field in an uninitialized object. */
1149 /* This is only allowed when a field of an uninitialized 'this' object is */
1150 /* written inside an initialization method */
1152 classinfo *initclass;
1153 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1156 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1157 return resolveFailed;
1160 /* XXX check that class of field == refmethod->class */
1161 initclass = referer; /* XXX classrefs */
1162 assert(initclass->state & CLASS_LINKED);
1164 typeinfo_init_classinfo(&tinfo, initclass);
1168 insttip = instanceti;
1171 result = resolve_lazy_subtype_checks(refmethod,
1173 CLASSREF_OR_CLASSINFO(container),
1174 resolveLinkageError);
1175 if (result != resolveSucceeded)
1178 /* check protected access */
1180 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1182 result = resolve_lazy_subtype_checks(refmethod,
1184 CLASSREF_OR_CLASSINFO(referer),
1185 resolveIllegalAccessError);
1186 if (result != resolveSucceeded)
1192 /* for PUT* instructions we have to check the constraints on the value type */
1195 assert(fieldtyperef);
1197 /* check subtype constraints */
1198 result = resolve_lazy_subtype_checks(refmethod,
1200 CLASSREF_OR_CLASSINFO(fieldtyperef),
1201 resolveLinkageError);
1203 if (result != resolveSucceeded)
1207 /* impose loading constraint on field type */
1209 if (fi->type == TYPE_ADR) {
1210 assert(fieldtyperef);
1211 if (!classcache_add_constraint(declarer->classloader,
1212 referer->classloader,
1213 fieldtyperef->name))
1214 return resolveFailed;
1217 /* XXX impose loading constraint on instance? */
1220 return resolveSucceeded;
1222 #endif /* defined(ENABLE_VERIFIER) */
1224 /* resolve_field_lazy **********************************************************
1226 Resolve an unresolved field reference lazily
1228 NOTE: This function does NOT do any verification checks. In case of a
1229 successful resolution, you must call resolve_field_verifier_checks
1230 in order to perform the necessary checks!
1233 refmethod........the referer method
1234 fieldref.........the field reference
1237 resolveSucceeded.....the reference has been resolved
1238 resolveDeferred......the resolving could not be performed lazily
1239 resolveFailed........resolving failed, an exception has been thrown.
1241 *******************************************************************************/
1243 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1244 constant_FMIref *fieldref)
1247 classinfo *container;
1252 /* the class containing the reference */
1254 referer = refmethod->class;
1257 /* check if the field itself is already resolved */
1259 if (IS_FMIREF_RESOLVED(fieldref))
1260 return resolveSucceeded;
1262 /* first we must resolve the class containg the field */
1264 /* XXX can/may lazyResolving trigger linking? */
1266 if (!resolve_class_from_name(referer, refmethod,
1267 fieldref->p.classref->name, resolveLazy, true, true, &container))
1269 /* the class reference could not be resolved */
1270 return resolveFailed; /* exception */
1273 return resolveDeferred; /* be lazy */
1275 assert(container->state & CLASS_LINKED);
1277 /* now we must find the declaration of the field in `container`
1278 * or one of its superclasses */
1280 fi = class_resolvefield(container,
1281 fieldref->name, fieldref->descriptor,
1284 /* The field does not exist. But since we were called lazily, */
1285 /* this error must not be reported now. (It will be reported */
1286 /* if eager resolving of this field is ever tried.) */
1288 exceptions_clear_exception();
1289 return resolveDeferred; /* be lazy */
1292 /* cache the result of the resolution */
1294 fieldref->p.field = fi;
1297 return resolveSucceeded;
1300 /* resolve_field ***************************************************************
1302 Resolve an unresolved field reference
1305 ref..............struct containing the reference
1306 mode.............mode of resolution:
1307 resolveLazy...only resolve if it does not
1308 require loading classes
1309 resolveEager..load classes if necessary
1312 *result..........set to the result of resolution, or to NULL if
1313 the reference has not been resolved
1314 In the case of an exception, *result is
1315 guaranteed to be set to NULL.
1318 true.............everything ok
1319 (*result may still be NULL for resolveLazy)
1320 false............an exception has been thrown
1322 *******************************************************************************/
1324 bool resolve_field(unresolved_field *ref,
1325 resolve_mode_t mode,
1329 classinfo *container;
1330 classinfo *declarer;
1331 constant_classref *fieldtyperef;
1333 resolve_result_t checkresult;
1337 assert(mode == resolveLazy || mode == resolveEager);
1341 #ifdef RESOLVE_VERBOSE
1342 unresolved_field_debug_dump(ref,stdout);
1345 /* the class containing the reference */
1347 referer = ref->referermethod->class;
1350 /* check if the field itself is already resolved */
1351 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1352 fi = ref->fieldref->p.field;
1353 container = fi->class;
1354 goto resolved_the_field;
1357 /* first we must resolve the class containg the field */
1358 if (!resolve_class_from_name(referer,ref->referermethod,
1359 ref->fieldref->p.classref->name,mode,true,true,&container))
1361 /* the class reference could not be resolved */
1362 return false; /* exception */
1365 return true; /* be lazy */
1368 assert(container->state & CLASS_LOADED);
1369 assert(container->state & CLASS_LINKED);
1371 /* now we must find the declaration of the field in `container`
1372 * or one of its superclasses */
1374 #ifdef RESOLVE_VERBOSE
1375 printf(" resolving field in class...\n");
1378 fi = class_resolvefield(container,
1379 ref->fieldref->name,ref->fieldref->descriptor,
1382 if (mode == resolveLazy) {
1383 /* The field does not exist. But since we were called lazily, */
1384 /* this error must not be reported now. (It will be reported */
1385 /* if eager resolving of this field is ever tried.) */
1387 exceptions_clear_exception();
1388 return true; /* be lazy */
1391 return false; /* exception */
1394 /* cache the result of the resolution */
1395 ref->fieldref->p.field = fi;
1399 #ifdef ENABLE_VERIFIER
1400 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1401 /* that no missing parts of an instruction will be accessed. */
1403 checkresult = resolve_field_verifier_checks(
1408 NULL, /* instanceti, handled by constraints below */
1409 NULL, /* valueti, handled by constraints below */
1410 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1411 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1413 if (checkresult != resolveSucceeded)
1414 return (bool) checkresult;
1416 declarer = fi->class;
1418 assert(declarer->state & CLASS_LOADED);
1419 assert(declarer->state & CLASS_LINKED);
1421 /* for non-static accesses we have to check the constraints on the */
1424 if (!(ref->flags & RESOLVE_STATIC)) {
1425 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1426 &(ref->instancetypes),
1427 CLASSREF_OR_CLASSINFO(container),
1428 mode, resolveLinkageError);
1429 if (checkresult != resolveSucceeded)
1430 return (bool) checkresult;
1433 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1435 /* for PUT* instructions we have to check the constraints on the value type */
1436 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1437 assert(fieldtyperef);
1438 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1439 /* check subtype constraints */
1440 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1441 &(ref->valueconstraints),
1442 CLASSREF_OR_CLASSINFO(fieldtyperef),
1443 mode, resolveLinkageError);
1444 if (checkresult != resolveSucceeded)
1445 return (bool) checkresult;
1449 /* check protected access */
1450 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1451 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1452 &(ref->instancetypes),
1453 CLASSREF_OR_CLASSINFO(referer),
1455 resolveIllegalAccessError);
1456 if (checkresult != resolveSucceeded)
1457 return (bool) checkresult;
1461 #endif /* ENABLE_VERIFIER */
1469 /* resolve_field_eager *********************************************************
1471 Resolve an unresolved field reference eagerly.
1474 ref..............struct containing the reference
1477 fieldinfo * to the field, or
1478 NULL if an exception has been thrown
1480 *******************************************************************************/
1482 fieldinfo * resolve_field_eager(unresolved_field *ref)
1486 if (!resolve_field(ref,resolveEager,&fi))
1492 /******************************************************************************/
1493 /* METHOD RESOLUTION */
1494 /******************************************************************************/
1496 /* resolve_method_invokespecial_lookup *****************************************
1498 Do the special lookup for methods invoked by INVOKESPECIAL
1501 refmethod........the method containing the reference
1502 mi...............the methodinfo of the resolved method
1505 a methodinfo *...the result of the lookup,
1506 NULL.............an exception has been thrown
1508 *******************************************************************************/
1510 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1513 classinfo *declarer;
1519 /* get referer and declarer classes */
1521 referer = refmethod->class;
1524 declarer = mi->class;
1526 assert(referer->state & CLASS_LINKED);
1528 /* checks for INVOKESPECIAL: */
1529 /* for <init> and methods of the current class we don't need any */
1530 /* special checks. Otherwise we must verify that the called method */
1531 /* belongs to a super class of the current class */
1533 if ((referer != declarer) && (mi->name != utf_init)) {
1534 /* check that declarer is a super class of the current class */
1536 if (!class_issubclass(referer,declarer)) {
1537 exceptions_throw_verifyerror(refmethod,
1538 "INVOKESPECIAL calling non-super class method");
1542 /* if the referer has ACC_SUPER set, we must do the special */
1543 /* lookup starting with the direct super class of referer */
1545 if ((referer->flags & ACC_SUPER) != 0) {
1546 mi = class_resolvemethod(referer->super.cls,
1551 /* the spec calls for an AbstractMethodError in this case */
1553 exceptions_throw_abstractmethoderror();
1564 /* resolve_method_verifier_checks ******************************************
1566 Do the verifier checks necessary after a method has been resolved.
1569 refmethod........the method containing the reference
1570 methodref........the method reference
1571 mi...............the methodinfo of the resolved method
1572 invokestatic.....true if the method is invoked by INVOKESTATIC
1575 resolveSucceeded....everything ok
1576 resolveDeferred.....tests could not be done, have been deferred
1577 resolveFailed.......exception has been thrown
1579 *******************************************************************************/
1581 #if defined(ENABLE_VERIFIER)
1582 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1583 constant_FMIref *methodref,
1587 classinfo *declarer;
1597 #ifdef RESOLVE_VERBOSE
1598 printf("resolve_method_verifier_checks\n");
1599 printf(" flags: %02x\n",mi->flags);
1602 /* get the classinfos and the method descriptor */
1604 referer = refmethod->class;
1607 declarer = mi->class;
1612 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1613 /* a static method is accessed via an instance, or vice versa */
1614 exceptions_throw_incompatibleclasschangeerror(declarer,
1615 (mi->flags & ACC_STATIC)
1616 ? "static method called via instance"
1617 : "instance method called without instance");
1619 return resolveFailed;
1622 /* check access rights */
1624 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1625 /* XXX clean this up. this should be in exceptions.c */
1628 utf_bytes(declarer->name) +
1629 utf_bytes(mi->name) +
1630 utf_bytes(mi->descriptor) +
1631 utf_bytes(referer->name) +
1634 msg = MNEW(char, msglen);
1636 strcpy(msg, "method is not accessible (");
1637 utf_cat_classname(msg, declarer->name);
1639 utf_cat(msg, mi->name);
1640 utf_cat(msg, mi->descriptor);
1641 strcat(msg, " from ");
1642 utf_cat_classname(msg, referer->name);
1645 u = utf_new_char(msg);
1647 MFREE(msg, char, msglen);
1649 exceptions_throw_illegalaccessexception(u);
1651 return resolveFailed; /* exception */
1656 return resolveSucceeded;
1658 #endif /* defined(ENABLE_VERIFIER) */
1661 /* resolve_method_instance_type_checks *****************************************
1663 Check the instance type of a method invocation.
1666 refmethod........the method containing the reference
1667 mi...............the methodinfo of the resolved method
1668 instanceti.......typeinfo of the instance slot
1669 invokespecial....true if the method is invoked by INVOKESPECIAL
1672 resolveSucceeded....everything ok
1673 resolveDeferred.....tests could not be done, have been deferred
1674 resolveFailed.......exception has been thrown
1676 *******************************************************************************/
1678 #if defined(ENABLE_VERIFIER)
1679 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1681 typeinfo *instanceti,
1686 resolve_result_t result;
1688 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1689 { /* XXX clean up */
1690 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1691 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1692 : CLASSREF_OR_CLASSINFO(refmethod->class);
1694 if (!typeinfo_init_class(tip, initclass))
1701 result = resolve_lazy_subtype_checks(refmethod,
1703 CLASSREF_OR_CLASSINFO(mi->class),
1704 resolveLinkageError);
1705 if (result != resolveSucceeded)
1708 /* check protected access */
1710 /* XXX use other `declarer` than mi->class? */
1711 if (((mi->flags & ACC_PROTECTED) != 0)
1712 && !SAME_PACKAGE(mi->class, refmethod->class))
1714 result = resolve_lazy_subtype_checks(refmethod,
1716 CLASSREF_OR_CLASSINFO(refmethod->class),
1717 resolveIllegalAccessError);
1718 if (result != resolveSucceeded)
1724 return resolveSucceeded;
1726 #endif /* defined(ENABLE_VERIFIER) */
1729 /* resolve_method_param_type_checks ********************************************
1731 Check non-instance parameter types of a method invocation.
1734 jd...............jitdata of the method doing the call
1735 refmethod........the method containing the reference
1736 iptr.............the invoke instruction
1737 mi...............the methodinfo of the resolved method
1738 invokestatic.....true if the method is invoked by INVOKESTATIC
1741 resolveSucceeded....everything ok
1742 resolveDeferred.....tests could not be done, have been deferred
1743 resolveFailed.......exception has been thrown
1745 *******************************************************************************/
1747 #if defined(ENABLE_VERIFIER)
1748 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1749 methodinfo *refmethod,
1755 resolve_result_t result;
1757 typedesc *paramtypes;
1764 instancecount = (invokestatic) ? 0 : 1;
1766 /* check subtype constraints for TYPE_ADR parameters */
1768 md = mi->parseddesc;
1769 paramtypes = md->paramtypes;
1771 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1772 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1773 type = md->paramtypes[i+instancecount].type;
1776 assert(type == param->type);
1778 if (type == TYPE_ADR) {
1779 result = resolve_lazy_subtype_checks(refmethod,
1781 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1782 resolveLinkageError);
1783 if (result != resolveSucceeded)
1790 return resolveSucceeded;
1792 #endif /* defined(ENABLE_VERIFIER) */
1795 /* resolve_method_param_type_checks_stackbased *********************************
1797 Check non-instance parameter types of a method invocation.
1800 refmethod........the method containing the reference
1801 mi...............the methodinfo of the resolved method
1802 invokestatic.....true if the method is invoked by INVOKESTATIC
1803 stack............TOS before the INVOKE instruction
1806 resolveSucceeded....everything ok
1807 resolveDeferred.....tests could not be done, have been deferred
1808 resolveFailed.......exception has been thrown
1810 *******************************************************************************/
1812 #if defined(ENABLE_VERIFIER)
1813 resolve_result_t resolve_method_param_type_checks_stackbased(
1814 methodinfo *refmethod,
1817 typedescriptor *stack)
1819 typedescriptor *param;
1820 resolve_result_t result;
1822 typedesc *paramtypes;
1827 instancecount = (invokestatic) ? 0 : 1;
1829 /* check subtype constraints for TYPE_ADR parameters */
1831 md = mi->parseddesc;
1832 paramtypes = md->paramtypes;
1834 param = stack - (md->paramslots - 1 - instancecount);
1836 for (i = instancecount; i < md->paramcount; ++i) {
1837 type = md->paramtypes[i].type;
1839 assert(type == param->type);
1841 if (type == TYPE_ADR) {
1842 result = resolve_lazy_subtype_checks(refmethod,
1844 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1845 resolveLinkageError);
1846 if (result != resolveSucceeded)
1850 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1855 return resolveSucceeded;
1857 #endif /* defined(ENABLE_VERIFIER) */
1860 /* resolve_method_loading_constraints ******************************************
1862 Impose loading constraints on the parameters and return type of the
1866 referer..........the class refering to the method
1867 mi...............the method
1870 true................everything ok
1871 false...............an exception has been thrown
1873 *******************************************************************************/
1875 #if defined(ENABLE_VERIFIER)
1876 bool resolve_method_loading_constraints(classinfo *referer,
1880 typedesc *paramtypes;
1885 /* impose loading constraints on parameters (including instance) */
1887 md = mi->parseddesc;
1888 paramtypes = md->paramtypes;
1889 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1891 for (i = 0; i < md->paramcount; i++) {
1892 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1893 if (i < instancecount) {
1894 /* The type of the 'this' pointer is the class containing */
1895 /* the method definition. Since container is the same as, */
1896 /* or a subclass of declarer, we also constrain declarer */
1897 /* by transitivity of loading constraints. */
1898 name = mi->class->name;
1901 name = paramtypes[i].classref->name;
1904 /* The caller (referer) and the callee (container) must agree */
1905 /* on the types of the parameters. */
1906 if (!classcache_add_constraint(referer->classloader,
1907 mi->class->classloader, name))
1908 return false; /* exception */
1912 /* impose loading constraint onto return type */
1914 if (md->returntype.type == TYPE_ADR) {
1915 /* The caller (referer) and the callee (container) must agree */
1916 /* on the return type. */
1917 if (!classcache_add_constraint(referer->classloader,
1918 mi->class->classloader,
1919 md->returntype.classref->name))
1920 return false; /* exception */
1927 #endif /* defined(ENABLE_VERIFIER) */
1930 /* resolve_method_lazy *********************************************************
1932 Resolve an unresolved method reference lazily
1934 NOTE: This function does NOT do any verification checks. In case of a
1935 successful resolution, you must call resolve_method_verifier_checks
1936 in order to perform the necessary checks!
1939 refmethod........the referer method
1940 methodref........the method reference
1941 invokespecial....true if this is an INVOKESPECIAL instruction
1944 resolveSucceeded.....the reference has been resolved
1945 resolveDeferred......the resolving could not be performed lazily
1946 resolveFailed........resolving failed, an exception has been thrown.
1948 *******************************************************************************/
1950 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1951 constant_FMIref *methodref,
1955 classinfo *container;
1960 #ifdef RESOLVE_VERBOSE
1961 printf("resolve_method_lazy\n");
1964 /* the class containing the reference */
1966 referer = refmethod->class;
1969 /* check if the method itself is already resolved */
1971 if (IS_FMIREF_RESOLVED(methodref))
1972 return resolveSucceeded;
1974 /* first we must resolve the class containg the method */
1976 if (!resolve_class_from_name(referer, refmethod,
1977 methodref->p.classref->name, resolveLazy, true, true, &container))
1979 /* the class reference could not be resolved */
1980 return resolveFailed; /* exception */
1983 return resolveDeferred; /* be lazy */
1985 assert(container->state & CLASS_LINKED);
1987 /* now we must find the declaration of the method in `container`
1988 * or one of its superclasses */
1990 if (container->flags & ACC_INTERFACE) {
1991 mi = class_resolveinterfacemethod(container,
1993 methodref->descriptor,
1997 mi = class_resolveclassmethod(container,
1999 methodref->descriptor,
2004 /* The method does not exist. But since we were called lazily, */
2005 /* this error must not be reported now. (It will be reported */
2006 /* if eager resolving of this method is ever tried.) */
2008 exceptions_clear_exception();
2009 return resolveDeferred; /* be lazy */
2012 if (invokespecial) {
2013 mi = resolve_method_invokespecial_lookup(refmethod, mi);
2015 return resolveFailed; /* exception */
2018 /* have the method params already been parsed? no, do it. */
2020 if (!mi->parseddesc->params)
2021 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2022 return resolveFailed;
2024 /* cache the result of the resolution */
2026 methodref->p.method = mi;
2030 return resolveSucceeded;
2033 /* resolve_method **************************************************************
2035 Resolve an unresolved method reference
2038 ref..............struct containing the reference
2039 mode.............mode of resolution:
2040 resolveLazy...only resolve if it does not
2041 require loading classes
2042 resolveEager..load classes if necessary
2045 *result..........set to the result of resolution, or to NULL if
2046 the reference has not been resolved
2047 In the case of an exception, *result is
2048 guaranteed to be set to NULL.
2051 true.............everything ok
2052 (*result may still be NULL for resolveLazy)
2053 false............an exception has been thrown
2055 *******************************************************************************/
2057 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2060 classinfo *container;
2061 classinfo *declarer;
2063 typedesc *paramtypes;
2066 resolve_result_t checkresult;
2070 assert(mode == resolveLazy || mode == resolveEager);
2072 #ifdef RESOLVE_VERBOSE
2073 unresolved_method_debug_dump(ref,stdout);
2078 /* the class containing the reference */
2080 referer = ref->referermethod->class;
2083 /* check if the method itself is already resolved */
2085 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2086 mi = ref->methodref->p.method;
2087 container = mi->class;
2088 goto resolved_the_method;
2091 /* first we must resolve the class containing the method */
2093 if (!resolve_class_from_name(referer,ref->referermethod,
2094 ref->methodref->p.classref->name,mode,true,true,&container))
2096 /* the class reference could not be resolved */
2097 return false; /* exception */
2100 return true; /* be lazy */
2103 assert(container->state & CLASS_LINKED);
2105 /* now we must find the declaration of the method in `container`
2106 * or one of its superclasses */
2108 if (container->flags & ACC_INTERFACE) {
2109 mi = class_resolveinterfacemethod(container,
2110 ref->methodref->name,
2111 ref->methodref->descriptor,
2115 mi = class_resolveclassmethod(container,
2116 ref->methodref->name,
2117 ref->methodref->descriptor,
2122 if (mode == resolveLazy) {
2123 /* The method does not exist. But since we were called lazily, */
2124 /* this error must not be reported now. (It will be reported */
2125 /* if eager resolving of this method is ever tried.) */
2127 exceptions_clear_exception();
2128 return true; /* be lazy */
2131 return false; /* exception */ /* XXX set exceptionptr? */
2134 /* { the method reference has been resolved } */
2136 if (ref->flags & RESOLVE_SPECIAL) {
2137 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2139 return false; /* exception */
2142 /* have the method params already been parsed? no, do it. */
2144 if (!mi->parseddesc->params)
2145 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2148 /* cache the resolution */
2150 ref->methodref->p.method = mi;
2152 resolved_the_method:
2154 #ifdef ENABLE_VERIFIER
2157 checkresult = resolve_method_verifier_checks(
2161 (ref->flags & RESOLVE_STATIC));
2163 if (checkresult != resolveSucceeded)
2164 return (bool) checkresult;
2166 /* impose loading constraints on params and return type */
2168 if (!resolve_method_loading_constraints(referer, mi))
2171 declarer = mi->class;
2173 assert(referer->state & CLASS_LINKED);
2175 /* for non-static methods we have to check the constraints on the */
2178 if (!(ref->flags & RESOLVE_STATIC)) {
2179 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2180 &(ref->instancetypes),
2181 CLASSREF_OR_CLASSINFO(container),
2183 resolveLinkageError);
2184 if (checkresult != resolveSucceeded)
2185 return (bool) checkresult;
2192 /* check subtype constraints for TYPE_ADR parameters */
2194 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2195 paramtypes = mi->parseddesc->paramtypes;
2197 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2198 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2199 if (ref->paramconstraints) {
2200 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2201 ref->paramconstraints + i,
2202 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2204 resolveLinkageError);
2205 if (checkresult != resolveSucceeded)
2206 return (bool) checkresult;
2211 /* check protected access */
2213 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2215 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2216 &(ref->instancetypes),
2217 CLASSREF_OR_CLASSINFO(referer),
2219 resolveIllegalAccessError);
2220 if (checkresult != resolveSucceeded)
2221 return (bool) checkresult;
2224 #endif /* ENABLE_VERIFIER */
2231 /* resolve_method_eager ********************************************************
2233 Resolve an unresolved method reference eagerly.
2236 ref..............struct containing the reference
2239 methodinfo * to the method, or
2240 NULL if an exception has been thrown
2242 *******************************************************************************/
2244 methodinfo * resolve_method_eager(unresolved_method *ref)
2248 if (!resolve_method(ref,resolveEager,&mi))
2254 /******************************************************************************/
2255 /* CREATING THE DATA STRUCTURES */
2256 /******************************************************************************/
2258 #ifdef ENABLE_VERIFIER
2259 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2260 methodinfo *refmethod,
2261 unresolved_subtype_set *stset,
2263 utf *declaredclassname)
2271 #ifdef RESOLVE_VERBOSE
2272 printf("unresolved_subtype_set_from_typeinfo\n");
2273 #ifdef TYPEINFO_DEBUG
2274 typeinfo_print(stdout,tinfo,4);
2276 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2280 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2281 exceptions_throw_verifyerror(refmethod,
2282 "Invalid use of returnAddress");
2286 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2287 exceptions_throw_verifyerror(refmethod,
2288 "Invalid use of uninitialized object");
2292 /* the nulltype is always assignable */
2293 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2296 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2297 if (declaredclassname == utf_java_lang_Object
2298 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2303 if (tinfo->merged) {
2304 count = tinfo->merged->count;
2305 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2306 for (i=0; i<count; ++i) {
2307 classref_or_classinfo c = tinfo->merged->list[i];
2308 if (tinfo->dimension > 0) {
2309 /* a merge of array types */
2310 /* the merged list contains the possible _element_ types, */
2311 /* so we have to create array types with these elements. */
2312 if (IS_CLASSREF(c)) {
2313 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2316 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2319 stset->subtyperefs[i] = c;
2321 stset->subtyperefs[count].any = NULL; /* terminate */
2324 if ((IS_CLASSREF(tinfo->typeclass)
2325 ? tinfo->typeclass.ref->name
2326 : tinfo->typeclass.cls->name) == declaredclassname)
2328 /* the class names are the same */
2329 /* equality is guaranteed by the loading constraints */
2333 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2334 stset->subtyperefs[0] = tinfo->typeclass;
2335 stset->subtyperefs[1].any = NULL; /* terminate */
2342 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2345 #endif /* ENABLE_VERIFIER */
2347 /* create_unresolved_class *****************************************************
2349 Create an unresolved_class struct for the given class reference
2352 refmethod........the method triggering the resolution (if any)
2353 classref.........the class reference
2354 valuetype........value type to check against the resolved class
2355 may be NULL, if no typeinfo is available
2358 a pointer to a new unresolved_class struct, or
2359 NULL if an exception has been thrown
2361 *******************************************************************************/
2363 #ifdef ENABLE_VERIFIER
2364 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2365 constant_classref *classref,
2366 typeinfo *valuetype)
2368 unresolved_class *ref;
2370 #ifdef RESOLVE_VERBOSE
2371 printf("create_unresolved_class\n");
2372 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2374 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2375 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2377 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2380 ref = NEW(unresolved_class);
2381 ref->classref = classref;
2382 ref->referermethod = refmethod;
2385 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2386 &(ref->subtypeconstraints),valuetype,classref->name))
2390 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2395 #endif /* ENABLE_VERIFIER */
2397 /* resolve_create_unresolved_field *********************************************
2399 Create an unresolved_field struct for the given field access instruction
2402 referer..........the class containing the reference
2403 refmethod........the method triggering the resolution (if any)
2404 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2407 a pointer to a new unresolved_field struct, or
2408 NULL if an exception has been thrown
2410 *******************************************************************************/
2412 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2413 methodinfo *refmethod,
2416 unresolved_field *ref;
2417 constant_FMIref *fieldref = NULL;
2419 #ifdef RESOLVE_VERBOSE
2420 printf("create_unresolved_field\n");
2421 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2422 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2423 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2426 ref = NEW(unresolved_field);
2428 ref->referermethod = refmethod;
2429 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2431 switch (iptr->opc) {
2433 ref->flags |= RESOLVE_PUTFIELD;
2436 case ICMD_PUTFIELDCONST:
2437 ref->flags |= RESOLVE_PUTFIELD;
2440 case ICMD_PUTSTATIC:
2441 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2444 case ICMD_PUTSTATICCONST:
2445 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2451 case ICMD_GETSTATIC:
2452 ref->flags |= RESOLVE_STATIC;
2455 #if !defined(NDEBUG)
2461 fieldref = iptr->sx.s23.s3.fmiref;
2465 #ifdef RESOLVE_VERBOSE
2466 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2467 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2468 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2469 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2473 ref->fieldref = fieldref;
2478 /* resolve_constrain_unresolved_field ******************************************
2480 Record subtype constraints for a field access.
2483 ref..............the unresolved_field structure of the access
2484 referer..........the class containing the reference
2485 refmethod........the method triggering the resolution (if any)
2486 instanceti.......instance typeinfo, if available
2487 valueti..........value typeinfo, if available
2490 true.............everything ok
2491 false............an exception has been thrown
2493 *******************************************************************************/
2495 #if defined(ENABLE_VERIFIER)
2496 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2498 methodinfo *refmethod,
2499 typeinfo *instanceti,
2502 constant_FMIref *fieldref;
2509 fieldref = ref->fieldref;
2512 #ifdef RESOLVE_VERBOSE
2513 printf("constrain_unresolved_field\n");
2514 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2515 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2516 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2517 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2518 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2519 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2520 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2524 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2525 fd = fieldref->parseddesc.fd;
2528 /* record subtype constraints for the instance type, if any */
2532 /* The instanceslot must contain a reference to a non-array type */
2533 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2534 exceptions_throw_verifyerror(refmethod,
2535 "illegal instruction: field access on non-reference");
2538 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2539 exceptions_throw_verifyerror(refmethod,
2540 "illegal instruction: field access on array");
2544 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2545 TYPEINFO_IS_NEWOBJECT(*instanceti))
2547 /* The instruction writes a field in an uninitialized object. */
2548 /* This is only allowed when a field of an uninitialized 'this' object is */
2549 /* written inside an initialization method */
2551 classinfo *initclass;
2552 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2555 exceptions_throw_verifyerror(refmethod,
2556 "accessing field of uninitialized object");
2559 /* XXX check that class of field == refmethod->class */
2560 initclass = refmethod->class; /* XXX classrefs */
2561 assert(initclass->state & CLASS_LOADED);
2562 assert(initclass->state & CLASS_LINKED);
2564 typeinfo_init_classinfo(&tinfo, initclass);
2568 insttip = instanceti;
2570 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2571 &(ref->instancetypes), insttip,
2572 FIELDREF_CLASSNAME(fieldref)))
2576 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2579 /* record subtype constraints for the value type, if any */
2581 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2583 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2584 &(ref->valueconstraints), valueti,
2585 fieldref->parseddesc.fd->classref->name))
2589 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2594 #endif /* ENABLE_VERIFIER */
2596 /* resolve_create_unresolved_method ********************************************
2598 Create an unresolved_method struct for the given method invocation
2601 referer..........the class containing the reference
2602 refmethod........the method triggering the resolution (if any)
2603 iptr.............the INVOKE* instruction
2606 a pointer to a new unresolved_method struct, or
2607 NULL if an exception has been thrown
2609 *******************************************************************************/
2611 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2612 methodinfo *refmethod,
2613 constant_FMIref *methodref,
2617 unresolved_method *ref;
2621 #ifdef RESOLVE_VERBOSE
2622 printf("create_unresolved_method\n");
2623 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2624 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2625 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2626 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2627 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2630 /* allocate params if necessary */
2631 if (!methodref->parseddesc.md->params)
2632 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2633 (invokestatic) ? ACC_STATIC : ACC_NONE))
2636 /* create the data structure */
2637 ref = NEW(unresolved_method);
2638 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2639 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2640 ref->referermethod = refmethod;
2641 ref->methodref = methodref;
2642 ref->paramconstraints = NULL;
2643 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2649 /* resolve_constrain_unresolved_method_instance ********************************
2651 Record subtype constraints for the instance argument of a method call.
2654 ref..............the unresolved_method structure of the call
2655 referer..........the class containing the reference
2656 refmethod........the method triggering the resolution (if any)
2657 iptr.............the INVOKE* instruction
2660 true.............everything ok
2661 false............an exception has been thrown
2663 *******************************************************************************/
2665 #if defined(ENABLE_VERIFIER)
2666 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2667 methodinfo *refmethod,
2668 typeinfo *instanceti,
2671 constant_FMIref *methodref;
2672 constant_classref *instanceref;
2677 methodref = ref->methodref;
2680 /* XXX clean this up */
2681 instanceref = IS_FMIREF_RESOLVED(methodref)
2682 ? class_get_self_classref(methodref->p.method->class)
2683 : methodref->p.classref;
2685 #ifdef RESOLVE_VERBOSE
2686 printf("resolve_constrain_unresolved_method_instance\n");
2687 printf(" rmethod: "); method_println(refmethod);
2688 printf(" mref : "); method_methodref_println(methodref);
2691 /* record subtype constraints for the instance type, if any */
2693 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2694 { /* XXX clean up */
2695 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2696 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2697 : CLASSREF_OR_CLASSINFO(refmethod->class);
2699 if (!typeinfo_init_class(tip, initclass))
2706 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2707 &(ref->instancetypes),tip,instanceref->name))
2712 #endif /* defined(ENABLE_VERIFIER) */
2715 /* resolve_constrain_unresolved_method_params *********************************
2717 Record subtype constraints for the non-instance arguments of a method call.
2720 jd...............current jitdata (for looking up variables)
2721 ref..............the unresolved_method structure of the call
2722 refmethod........the method triggering the resolution (if any)
2723 iptr.............the INVOKE* instruction
2726 true.............everything ok
2727 false............an exception has been thrown
2729 *******************************************************************************/
2731 #if defined(ENABLE_VERIFIER)
2732 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2733 unresolved_method *ref,
2734 methodinfo *refmethod,
2737 constant_FMIref *methodref;
2745 methodref = ref->methodref;
2747 md = methodref->parseddesc.md;
2749 assert(md->params != NULL);
2751 #ifdef RESOLVE_VERBOSE
2752 printf("resolve_constrain_unresolved_method_params\n");
2753 printf(" rmethod: "); method_println(refmethod);
2754 printf(" mref : "); method_methodref_println(methodref);
2757 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2759 /* record subtype constraints for the parameter types, if any */
2761 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2762 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2763 type = md->paramtypes[i+instancecount].type;
2766 assert(type == param->type);
2768 if (type == TYPE_ADR) {
2769 if (!ref->paramconstraints) {
2770 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2771 for (j=md->paramcount-1-instancecount; j>i; --j)
2772 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2774 assert(ref->paramconstraints);
2775 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2776 ref->paramconstraints + i,&(param->typeinfo),
2777 md->paramtypes[i+instancecount].classref->name))
2781 if (ref->paramconstraints)
2782 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2788 #endif /* ENABLE_VERIFIER */
2791 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2793 Record subtype constraints for the non-instance arguments of a method call.
2796 ref..............the unresolved_method structure of the call
2797 refmethod........the method triggering the resolution (if any)
2798 stack............TOS before the INVOKE instruction
2801 true.............everything ok
2802 false............an exception has been thrown
2804 *******************************************************************************/
2806 #if defined(ENABLE_VERIFIER)
2807 bool resolve_constrain_unresolved_method_params_stackbased(
2808 unresolved_method *ref,
2809 methodinfo *refmethod,
2810 typedescriptor *stack)
2812 constant_FMIref *methodref;
2813 typedescriptor *param;
2820 methodref = ref->methodref;
2822 md = methodref->parseddesc.md;
2824 assert(md->params != NULL);
2826 #ifdef RESOLVE_VERBOSE
2827 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2828 printf(" rmethod: "); method_println(refmethod);
2829 printf(" mref : "); method_methodref_println(methodref);
2832 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2834 /* record subtype constraints for the parameter types, if any */
2836 param = stack - (md->paramslots - 1 - instancecount);
2838 for (i = instancecount; i < md->paramcount; ++i) {
2839 type = md->paramtypes[i].type;
2841 assert(type == param->type);
2843 if (type == TYPE_ADR) {
2844 if (!ref->paramconstraints) {
2845 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2846 for (j = 0; j < i - instancecount; ++j)
2847 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2849 assert(ref->paramconstraints);
2850 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2851 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2852 md->paramtypes[i].classref->name))
2856 if (ref->paramconstraints)
2857 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2860 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2865 #endif /* ENABLE_VERIFIER */
2868 /******************************************************************************/
2869 /* FREEING MEMORY */
2870 /******************************************************************************/
2872 #ifdef ENABLE_VERIFIER
2873 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2876 classref_or_classinfo *p = list;
2878 /* this is silly. we *only* need to count the elements for MFREE */
2881 MFREE(list,classref_or_classinfo,(p - list));
2884 #endif /* ENABLE_VERIFIER */
2886 /* unresolved_class_free *******************************************************
2888 Free the memory used by an unresolved_class
2891 ref..............the unresolved_class
2893 *******************************************************************************/
2895 void unresolved_class_free(unresolved_class *ref)
2899 #ifdef ENABLE_VERIFIER
2900 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2902 FREE(ref,unresolved_class);
2905 /* unresolved_field_free *******************************************************
2907 Free the memory used by an unresolved_field
2910 ref..............the unresolved_field
2912 *******************************************************************************/
2914 void unresolved_field_free(unresolved_field *ref)
2918 #ifdef ENABLE_VERIFIER
2919 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2920 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2922 FREE(ref,unresolved_field);
2925 /* unresolved_method_free ******************************************************
2927 Free the memory used by an unresolved_method
2930 ref..............the unresolved_method
2932 *******************************************************************************/
2934 void unresolved_method_free(unresolved_method *ref)
2938 #ifdef ENABLE_VERIFIER
2939 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2940 if (ref->paramconstraints) {
2942 int count = ref->methodref->parseddesc.md->paramcount;
2944 for (i=0; i<count; ++i)
2945 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2946 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2949 FREE(ref,unresolved_method);
2952 /******************************************************************************/
2954 /******************************************************************************/
2956 #if !defined(NDEBUG)
2958 /* unresolved_subtype_set_debug_dump *******************************************
2960 Print debug info for unresolved_subtype_set to stream
2963 stset............the unresolved_subtype_set
2964 file.............the stream
2966 *******************************************************************************/
2968 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2970 classref_or_classinfo *p;
2972 if (SUBTYPESET_IS_EMPTY(*stset)) {
2973 fprintf(file," (empty)\n");
2976 p = stset->subtyperefs;
2977 for (;p->any; ++p) {
2978 if (IS_CLASSREF(*p)) {
2979 fprintf(file," ref: ");
2980 utf_fprint_printable_ascii(file,p->ref->name);
2983 fprintf(file," cls: ");
2984 utf_fprint_printable_ascii(file,p->cls->name);
2991 /* unresolved_class_debug_dump *************************************************
2993 Print debug info for unresolved_class to stream
2996 ref..............the unresolved_class
2997 file.............the stream
2999 *******************************************************************************/
3001 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3003 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3005 fprintf(file," referer : ");
3006 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3007 fprintf(file," refmethod : ");
3008 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3009 fprintf(file," refmethodd: ");
3010 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3011 fprintf(file," classname : ");
3012 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3013 fprintf(file," subtypeconstraints:\n");
3014 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3018 /* unresolved_field_debug_dump *************************************************
3020 Print debug info for unresolved_field to stream
3023 ref..............the unresolved_field
3024 file.............the stream
3026 *******************************************************************************/
3028 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3030 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3032 fprintf(file," referer : ");
3033 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3034 fprintf(file," refmethod : ");
3035 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3036 fprintf(file," refmethodd: ");
3037 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3038 fprintf(file," classname : ");
3039 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3040 fprintf(file," name : ");
3041 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3042 fprintf(file," descriptor: ");
3043 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3044 fprintf(file," parseddesc: ");
3045 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3046 fprintf(file," flags : %04x\n",ref->flags);
3047 fprintf(file," instancetypes:\n");
3048 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3049 fprintf(file," valueconstraints:\n");
3050 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3054 /* unresolved_method_debug_dump ************************************************
3056 Print debug info for unresolved_method to stream
3059 ref..............the unresolved_method
3060 file.............the stream
3062 *******************************************************************************/
3064 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3068 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3070 fprintf(file," referer : ");
3071 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3072 fprintf(file," refmethod : ");
3073 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3074 fprintf(file," refmethodd: ");
3075 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3076 fprintf(file," classname : ");
3077 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3078 fprintf(file," name : ");
3079 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3080 fprintf(file," descriptor: ");
3081 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3082 fprintf(file," parseddesc: ");
3083 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3084 fprintf(file," flags : %04x\n",ref->flags);
3085 fprintf(file," instancetypes:\n");
3086 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3087 fprintf(file," paramconstraints:\n");
3088 if (ref->paramconstraints) {
3089 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3090 fprintf(file," param %d:\n",i);
3091 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3095 fprintf(file," (empty)\n");
3099 #endif /* !defined(NDEBUG) */
3103 * These are local overrides for various environment variables in Emacs.
3104 * Please do not remove this and leave it at the end of the file, where
3105 * Emacs will automagically detect them.
3106 * ---------------------------------------------------------------------
3109 * indent-tabs-mode: t
3113 * vim:noexpandtab:sw=4:ts=4: