1 /* src/vm/resolve.cpp - resolving classes/interfaces/fields/methods
3 Copyright (C) 1996-2011
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 #include "mm/memory.hpp"
34 #include "vm/access.hpp"
35 #include "vm/classcache.hpp"
36 #include "vm/descriptor.hpp"
37 #include "vm/exceptions.hpp"
38 #include "vm/global.h"
39 #include "vm/globals.hpp"
40 #include "vm/linker.hpp"
41 #include "vm/loader.hpp"
42 #include "vm/options.h"
43 #include "vm/primitive.hpp"
44 #include "vm/resolve.hpp"
46 #include "vm/jit/jit.hpp"
47 #include "vm/jit/verify/typeinfo.hpp"
50 /******************************************************************************/
52 /******************************************************************************/
54 /*#define RESOLVE_VERBOSE*/
56 /* resolve_handle_pending_exception ********************************************
58 Convert a pending ClassNotFoundException into a
59 NoClassDefFoundError if requested.
61 See: hotspot/src/share/vm/classfile/systemDictionary.cpp
62 (handle_resolution_exception)
65 classname .... name of the class currently resolved
66 throwError ... if true throw a NoClassDefFoundError instead of
67 a ClassNotFoundException
69 *******************************************************************************/
71 void resolve_handle_pending_exception(bool throwError)
75 /* Get the current exception. */
77 e = exceptions_get_exception();
80 if (throwError == true) {
81 /* Convert ClassNotFoundException to
82 NoClassDefFoundError. */
84 if (builtin_instanceof(e, class_java_lang_ClassNotFoundException)) {
85 /* Clear exception, because we are calling Java code
88 exceptions_clear_exception();
90 /* create new error */
92 exceptions_throw_noclassdeffounderror_cause(e);
99 /* An exception conversion was not requested. Simply
108 /******************************************************************************/
109 /* CLASS RESOLUTION */
110 /******************************************************************************/
112 /* resolve_class_from_name *****************************************************
114 Resolve a symbolic class reference
117 referer..........the class containing the reference
118 refmethod........the method from which resolution was triggered
119 (may be NULL if not applicable)
120 classname........class name to resolve
121 mode.............mode of resolution:
122 resolveLazy...only resolve if it does not
123 require loading classes
124 resolveEager..load classes if necessary
125 checkaccess......if true, access rights to the class are checked
126 link.............if true, guarantee that the returned class, if any,
130 *result..........set to result of resolution, or to NULL if
131 the reference has not been resolved
132 In the case of an exception, *result is
133 guaranteed to be set to NULL.
136 true.............everything ok
137 (*result may still be NULL for resolveLazy)
138 false............an exception has been thrown
141 The returned class is *not* guaranteed to be linked!
142 (It is guaranteed to be loaded, though.)
144 *******************************************************************************/
146 bool resolve_class_from_name(classinfo *referer,
147 methodinfo *refmethod,
164 assert(mode == resolveLazy || mode == resolveEager);
168 #ifdef RESOLVE_VERBOSE
169 printf("resolve_class_from_name(");
170 utf_fprint_printable_ascii(stdout,referer->name);
171 printf(",%p,",(void*)referer->classloader);
172 utf_fprint_printable_ascii(stdout,classname);
173 printf(",%d,%d)\n",(int)checkaccess,(int)link);
176 /* lookup if this class has already been loaded */
178 cls = classcache_lookup(referer->classloader, classname);
180 #ifdef RESOLVE_VERBOSE
181 printf(" lookup result: %p\n",(void*)cls);
185 /* resolve array types */
187 if (classname->text[0] == '[') {
188 utf_ptr = classname->text + 1;
189 len = classname->blength - 1;
191 /* classname is an array type name */
199 /* the component type is a reference type */
200 /* resolve the component type */
201 if (!resolve_class_from_name(referer,refmethod,
202 utf_new(utf_ptr,len),
203 mode,checkaccess,link,&cls))
204 return false; /* exception */
206 assert(mode == resolveLazy);
207 return true; /* be lazy */
209 /* create the array class */
210 cls = class_array_of(cls,false);
212 return false; /* exception */
216 /* the class has not been loaded, yet */
217 if (mode == resolveLazy)
218 return true; /* be lazy */
221 #ifdef RESOLVE_VERBOSE
222 printf(" loading...\n");
228 cls = load_class_from_classloader(classname, referer->classloader);
235 /* the class is now loaded */
237 assert(cls->state & CLASS_LOADED);
239 #ifdef RESOLVE_VERBOSE
240 printf(" checking access rights...\n");
243 /* check access rights of referer to refered class */
245 if (checkaccess && !access_is_accessible_class(referer,cls)) {
247 utf_bytes(cls->name) +
248 utf_bytes(referer->name) +
251 msg = MNEW(char, msglen);
253 strcpy(msg, "class is not accessible (");
254 utf_cat_classname(msg, cls->name);
255 strcat(msg, " from ");
256 utf_cat_classname(msg, referer->name);
259 u = utf_new_char(msg);
261 MFREE(msg, char, msglen);
263 exceptions_throw_illegalaccessexception(u);
265 return false; /* exception */
268 /* link the class if necessary */
270 if (!(cls->state & CLASS_LINKED))
271 if (!link_class(cls))
272 return false; /* exception */
274 assert(cls->state & CLASS_LINKED);
277 /* resolution succeeds */
278 #ifdef RESOLVE_VERBOSE
279 printf(" success.\n");
285 /* resolve_classref ************************************************************
287 Resolve a symbolic class reference
290 refmethod........the method from which resolution was triggered
291 (may be NULL if not applicable)
292 ref..............class reference
293 mode.............mode of resolution:
294 resolveLazy...only resolve if it does not
295 require loading classes
296 resolveEager..load classes if necessary
297 checkaccess......if true, access rights to the class are checked
298 link.............if true, guarantee that the returned class, if any,
302 *result..........set to result of resolution, or to NULL if
303 the reference has not been resolved
304 In the case of an exception, *result is
305 guaranteed to be set to NULL.
308 true.............everything ok
309 (*result may still be NULL for resolveLazy)
310 false............an exception has been thrown
312 *******************************************************************************/
314 bool resolve_classref(methodinfo *refmethod,
315 constant_classref *ref,
321 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
324 /* resolve_classref_or_classinfo ***********************************************
326 Resolve a symbolic class reference if necessary
328 NOTE: If given, refmethod->clazz is used as the referring class.
329 Otherwise, cls.ref->referer is used.
332 refmethod........the method from which resolution was triggered
333 (may be NULL if not applicable)
334 cls..............class reference or classinfo
335 mode.............mode of resolution:
336 resolveLazy...only resolve if it does not
337 require loading classes
338 resolveEager..load classes if necessary
339 checkaccess......if true, access rights to the class are checked
340 link.............if true, guarantee that the returned class, if any,
344 *result..........set to result of resolution, or to NULL if
345 the reference has not been resolved
346 In the case of an exception, *result is
347 guaranteed to be set to NULL.
350 true.............everything ok
351 (*result may still be NULL for resolveLazy)
352 false............an exception has been thrown
354 *******************************************************************************/
356 bool resolve_classref_or_classinfo(methodinfo *refmethod,
357 classref_or_classinfo cls,
367 assert(mode == resolveEager || mode == resolveLazy);
370 #ifdef RESOLVE_VERBOSE
371 printf("resolve_classref_or_classinfo(");
372 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
373 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
378 if (IS_CLASSREF(cls)) {
379 /* we must resolve this reference */
381 /* determine which class to use as the referer */
383 /* Common cases are refmethod == NULL or both referring classes */
384 /* being the same, so the referer usually is cls.ref->referer. */
385 /* There is one important case where it is not: When we do a */
386 /* deferred assignability check to a formal argument of a method, */
387 /* we must use refmethod->clazz (the caller's class) to resolve */
388 /* the type of the formal argument. */
390 referer = (refmethod) ? refmethod->clazz : cls.ref->referer;
392 if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
393 mode, checkaccess, link, &c))
394 goto return_exception;
397 /* cls has already been resolved */
399 assert(c->state & CLASS_LOADED);
401 assert(c || (mode == resolveLazy));
404 return true; /* be lazy */
407 assert(c->state & CLASS_LOADED);
410 if (!(c->state & CLASS_LINKED))
412 goto return_exception;
414 assert(c->state & CLASS_LINKED);
427 /* resolve_classref_or_classinfo_eager *****************************************
429 Resolve a symbolic class reference eagerly if necessary.
430 No attempt is made to link the class.
433 cls..............class reference or classinfo
434 checkaccess......if true, access rights to the class are checked
437 classinfo *......the resolved class
438 NULL.............an exception has been thrown
440 *******************************************************************************/
442 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
447 if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
454 /* resolve_class_from_typedesc *************************************************
456 Return a classinfo * for the given type descriptor
459 d................type descriptor
460 checkaccess......if true, access rights to the class are checked
461 link.............if true, guarantee that the returned class, if any,
464 *result..........set to result of resolution, or to NULL if
465 the reference has not been resolved
466 In the case of an exception, *result is
467 guaranteed to be set to NULL.
470 true.............everything ok
471 false............an exception has been thrown
474 This function always resolves eagerly.
476 *******************************************************************************/
478 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
487 #ifdef RESOLVE_VERBOSE
488 printf("resolve_class_from_typedesc(");
489 descriptor_debug_print_typedesc(stdout,d);
490 printf(",%i,%i)\n",(int)checkaccess,(int)link);
493 if (d->type == TYPE_ADR) {
494 /* a reference type */
496 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
497 resolveEager,checkaccess,link,&cls))
498 return false; /* exception */
501 /* a primitive type */
503 cls = Primitive::get_class_by_type(d->primitivetype);
505 assert(cls->state & CLASS_LOADED);
507 if (!(cls->state & CLASS_LINKED))
508 if (!link_class(cls))
509 return false; /* exception */
513 assert(cls->state & CLASS_LOADED);
514 assert(!link || (cls->state & CLASS_LINKED));
516 #ifdef RESOLVE_VERBOSE
517 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
524 /******************************************************************************/
525 /* SUBTYPE SET CHECKS */
526 /******************************************************************************/
528 /* resolve_subtype_check *******************************************************
530 Resolve the given types lazily and perform a subtype check
533 refmethod........the method triggering the resolution
534 subtype..........checked to be a subtype of supertype
535 supertype........the super type to check agaings
536 mode.............mode of resolution:
537 resolveLazy...only resolve if it does not
538 require loading classes
539 resolveEager..load classes if necessary
540 error............which type of exception to throw if
541 the test fails. May be:
542 resolveLinkageError, or
543 resolveIllegalAccessError
544 IMPORTANT: If error==resolveIllegalAccessError,
545 then array types are not checked.
548 resolveSucceeded.....the check succeeded
549 resolveDeferred......the check could not be performed due to
550 unresolved types. (This can only happen for
551 mode == resolveLazy.)
552 resolveFailed........the check failed, an exception has been thrown.
555 The types are resolved first, so any
556 exception which may occurr during resolution may
557 be thrown by this function.
559 *******************************************************************************/
561 #if defined(ENABLE_VERIFIER)
562 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
563 classref_or_classinfo subtype,
564 classref_or_classinfo supertype,
577 assert(supertype.any);
578 assert(mode == resolveLazy || mode == resolveEager);
579 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
581 /* resolve the subtype */
583 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
584 /* the subclass could not be resolved. therefore we are sure that */
585 /* no instances of this subclass will ever exist -> skip this test */
586 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
587 exceptions_clear_exception();
588 return resolveSucceeded;
591 return resolveDeferred; /* be lazy */
593 assert(subclass->state & CLASS_LINKED);
595 /* do not check access to protected members of arrays */
597 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
598 return resolveSucceeded;
601 /* perform the subtype check */
603 typeinfo_init_classinfo(&subti,subclass);
605 r = typeinfo_is_assignable_to_class(&subti,supertype);
606 if (r == typecheck_FAIL)
607 return resolveFailed; /* failed, exception is already set */
609 if (r == typecheck_MAYBE) {
610 assert(IS_CLASSREF(supertype));
611 if (mode == resolveEager) {
612 if (!resolve_classref_or_classinfo(refmethod,supertype,
613 resolveEager,false,true,
616 return resolveFailed;
618 assert(supertype.cls);
622 return resolveDeferred; /* be lazy */
626 /* sub class relationship is false */
628 #if defined(RESOLVE_VERBOSE)
629 printf("SUBTYPE CHECK FAILED!\n");
633 utf_bytes(subclass->name) +
634 utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
637 msg = MNEW(char, msglen);
639 strcpy(msg, (error == resolveIllegalAccessError) ?
640 "illegal access to protected member (" :
641 "subtype constraint violated (");
643 utf_cat_classname(msg, subclass->name);
644 strcat(msg, " is not a subclass of ");
645 utf_cat_classname(msg, CLASSREF_OR_CLASSINFO_NAME(supertype));
648 u = utf_new_char(msg);
650 if (error == resolveIllegalAccessError)
651 exceptions_throw_illegalaccessexception(u);
653 exceptions_throw_linkageerror(msg, NULL);
655 /* ATTENTION: We probably need msg for
656 exceptions_throw_linkageerror. */
658 MFREE(msg, char, msglen);
660 return resolveFailed; /* exception */
665 return resolveSucceeded;
667 #endif /* defined(ENABLE_VERIFIER) */
669 /* resolve_lazy_subtype_checks *************************************************
671 Resolve the types to check lazily and perform subtype checks
674 refmethod........the method triggering the resolution
675 subtinfo.........the typeinfo containing the subtypes
676 supertype........the supertype to test againgst
677 mode.............mode of resolution:
678 resolveLazy...only resolve if it does not
679 require loading classes
680 resolveEager..load classes if necessary
681 error............which type of exception to throw if
682 the test fails. May be:
683 resolveLinkageError, or
684 resolveIllegalAccessError
685 IMPORTANT: If error==resolveIllegalAccessError,
686 then array types in the set are skipped.
689 resolveSucceeded.....the check succeeded
690 resolveDeferred......the check could not be performed due to
692 resolveFailed........the check failed, an exception has been thrown.
695 The references in the set are resolved first, so any
696 exception which may occurr during resolution may
697 be thrown by this function.
699 *******************************************************************************/
701 #if defined(ENABLE_VERIFIER)
702 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
703 typeinfo_t *subtinfo,
704 classref_or_classinfo supertype,
709 resolve_result_t result;
713 assert(supertype.any);
714 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
716 /* returnAddresses are illegal here */
718 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
719 exceptions_throw_verifyerror(refmethod,
720 "Invalid use of returnAddress");
721 return resolveFailed;
724 /* uninitialized objects are illegal here */
726 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
727 exceptions_throw_verifyerror(refmethod,
728 "Invalid use of uninitialized object");
729 return resolveFailed;
732 /* the nulltype is always assignable */
734 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
735 return resolveSucceeded;
737 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
739 if (supertype.cls == class_java_lang_Object
740 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
741 && refmethod->clazz->classloader == NULL))
743 return resolveSucceeded;
746 if (subtinfo->merged) {
748 /* for a merged type we have to do a series of checks */
750 count = subtinfo->merged->count;
751 for (i=0; i<count; ++i) {
752 classref_or_classinfo c = subtinfo->merged->list[i];
753 if (subtinfo->dimension > 0) {
754 /* a merge of array types */
755 /* the merged list contains the possible _element_ types, */
756 /* so we have to create array types with these elements. */
757 if (IS_CLASSREF(c)) {
758 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
761 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
765 /* do the subtype check against the type c */
767 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
768 if (result != resolveSucceeded)
774 /* a single type, this is the common case, hopefully */
776 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
777 == CLASSREF_OR_CLASSINFO_NAME(supertype))
779 /* the class names are the same */
780 /* equality is guaranteed by the loading constraints */
781 return resolveSucceeded;
785 /* some other type name, try to perform the check lazily */
787 return resolve_subtype_check(refmethod,
788 subtinfo->typeclass,supertype,
795 return resolveSucceeded;
797 #endif /* defined(ENABLE_VERIFIER) */
799 /* resolve_and_check_subtype_set ***********************************************
801 Resolve the references in the given set and test subtype relationships
804 refmethod........the method triggering the resolution
805 ref..............a set of class/interface references
807 typeref..........the type to test against the set
808 mode.............mode of resolution:
809 resolveLazy...only resolve if it does not
810 require loading classes
811 resolveEager..load classes if necessary
812 error............which type of exception to throw if
813 the test fails. May be:
814 resolveLinkageError, or
815 resolveIllegalAccessError
816 IMPORTANT: If error==resolveIllegalAccessError,
817 then array types in the set are skipped.
820 resolveSucceeded.....the check succeeded
821 resolveDeferred......the check could not be performed due to
822 unresolved types. (This can only happen if
823 mode == resolveLazy.)
824 resolveFailed........the check failed, an exception has been thrown.
827 The references in the set are resolved first, so any
828 exception which may occurr during resolution may
829 be thrown by this function.
831 *******************************************************************************/
833 #if defined(ENABLE_VERIFIER)
834 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
835 unresolved_subtype_set *ref,
836 classref_or_classinfo typeref,
840 classref_or_classinfo *setp;
841 resolve_result_t checkresult;
846 assert(mode == resolveLazy || mode == resolveEager);
847 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
849 #if defined(RESOLVE_VERBOSE)
850 printf("resolve_and_check_subtype_set:\n");
851 unresolved_subtype_set_debug_dump(ref, stdout);
852 if (IS_CLASSREF(typeref))
853 class_classref_println(typeref.ref);
855 class_println(typeref.cls);
858 setp = ref->subtyperefs;
860 /* an empty set of tests always succeeds */
861 if (!setp || !setp->any) {
862 return resolveSucceeded;
865 /* first resolve the type if necessary */
866 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
867 return resolveFailed; /* exception */
869 return resolveDeferred; /* be lazy */
871 assert(typeref.cls->state & CLASS_LINKED);
873 /* iterate over the set members */
875 for (; setp->any; ++setp) {
876 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
877 #if defined(RESOLVE_VERBOSE)
878 if (checkresult != resolveSucceeded)
879 printf("SUBTYPE CHECK FAILED!\n");
881 if (checkresult != resolveSucceeded)
886 return resolveSucceeded;
888 #endif /* defined(ENABLE_VERIFIER) */
890 /******************************************************************************/
891 /* CLASS RESOLUTION */
892 /******************************************************************************/
894 /* resolve_class ***************************************************************
896 Resolve an unresolved class reference. The class is also linked.
899 ref..............struct containing the reference
900 mode.............mode of resolution:
901 resolveLazy...only resolve if it does not
902 require loading classes
903 resolveEager..load classes if necessary
904 checkaccess......if true, access rights to the class are checked
907 *result..........set to the result of resolution, or to NULL if
908 the reference has not been resolved
909 In the case of an exception, *result is
910 guaranteed to be set to NULL.
913 true.............everything ok
914 (*result may still be NULL for resolveLazy)
915 false............an exception has been thrown
917 *******************************************************************************/
919 #ifdef ENABLE_VERIFIER
920 bool resolve_class(unresolved_class *ref,
926 resolve_result_t checkresult;
930 assert(mode == resolveLazy || mode == resolveEager);
934 #ifdef RESOLVE_VERBOSE
935 unresolved_class_debug_dump(ref,stdout);
938 /* first we must resolve the class */
939 if (!resolve_classref(ref->referermethod,
940 ref->classref,mode,checkaccess,true,&cls))
942 /* the class reference could not be resolved */
943 return false; /* exception */
946 return true; /* be lazy */
949 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
951 /* now we check the subtype constraints */
953 checkresult = resolve_and_check_subtype_set(ref->referermethod,
954 &(ref->subtypeconstraints),
955 CLASSREF_OR_CLASSINFO(cls),
957 resolveLinkageError);
958 if (checkresult != resolveSucceeded)
959 return (bool) checkresult;
965 #endif /* ENABLE_VERIFIER */
967 /* resolve_classref_eager ******************************************************
969 Resolve an unresolved class reference eagerly. The class is also linked and
970 access rights to the class are checked.
973 ref..............constant_classref to the class
976 classinfo * to the class, or
977 NULL if an exception has been thrown
979 *******************************************************************************/
981 classinfo * resolve_classref_eager(constant_classref *ref)
985 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
991 /* resolve_classref_eager_nonabstract ******************************************
993 Resolve an unresolved class reference eagerly. The class is also linked and
994 access rights to the class are checked. A check is performed that the class
998 ref..............constant_classref to the class
1001 classinfo * to the class, or
1002 NULL if an exception has been thrown
1004 *******************************************************************************/
1006 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
1010 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
1013 /* ensure that the class is not abstract */
1015 if (c->flags & ACC_ABSTRACT) {
1016 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
1023 /* resolve_class_eager *********************************************************
1025 Resolve an unresolved class reference eagerly. The class is also linked and
1026 access rights to the class are checked.
1029 ref..............struct containing the reference
1032 classinfo * to the class, or
1033 NULL if an exception has been thrown
1035 *******************************************************************************/
1037 #ifdef ENABLE_VERIFIER
1038 classinfo * resolve_class_eager(unresolved_class *ref)
1042 if (!resolve_class(ref,resolveEager,true,&c))
1047 #endif /* ENABLE_VERIFIER */
1049 /* resolve_class_eager_no_access_check *****************************************
1051 Resolve an unresolved class reference eagerly. The class is also linked.
1052 Access rights are _not_ checked.
1055 ref..............struct containing the reference
1058 classinfo * to the class, or
1059 NULL if an exception has been thrown
1061 *******************************************************************************/
1063 #ifdef ENABLE_VERIFIER
1064 classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
1068 if (!resolve_class(ref, resolveEager, false, &c))
1073 #endif /* ENABLE_VERIFIER */
1075 /******************************************************************************/
1076 /* FIELD RESOLUTION */
1077 /******************************************************************************/
1079 /* resolve_field_verifier_checks *******************************************
1081 Do the verifier checks necessary after field has been resolved.
1084 refmethod........the method containing the reference
1085 fieldref.........the field reference
1086 container........the class where the field was found
1087 fi...............the fieldinfo of the resolved field
1088 instanceti.......instance typeinfo, if available
1089 valueti..........value typeinfo, if available
1090 isstatic.........true if this is a *STATIC* instruction
1091 isput............true if this is a PUT* instruction
1094 resolveSucceeded....everything ok
1095 resolveDeferred.....tests could not be done, have been deferred
1096 resolveFailed.......exception has been thrown
1098 *******************************************************************************/
1100 #if defined(ENABLE_VERIFIER)
1101 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
1102 constant_FMIref *fieldref,
1103 classinfo *container,
1105 typeinfo_t *instanceti,
1106 typeinfo_t *valueti,
1110 classinfo *declarer;
1112 resolve_result_t result;
1113 constant_classref *fieldtyperef;
1123 /* get the classinfos and the field type */
1125 referer = refmethod->clazz;
1128 declarer = fi->clazz;
1130 assert(referer->state & CLASS_LINKED);
1132 fieldtyperef = fieldref->parseddesc.fd->classref;
1137 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1140 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1141 /* a static field is accessed via an instance, or vice versa */
1142 exceptions_throw_incompatibleclasschangeerror(declarer,
1143 (fi->flags & ACC_STATIC)
1144 ? "static field accessed via instance"
1145 : "instance field accessed without instance");
1147 return resolveFailed;
1150 /* check access rights */
1152 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1154 utf_bytes(declarer->name) +
1155 utf_bytes(fi->name) +
1156 utf_bytes(referer->name) +
1159 msg = MNEW(char, msglen);
1161 strcpy(msg, "field is not accessible (");
1162 utf_cat_classname(msg, declarer->name);
1164 utf_cat(msg, fi->name);
1165 strcat(msg, " from ");
1166 utf_cat_classname(msg, referer->name);
1169 u = utf_new_char(msg);
1171 MFREE(msg, char, msglen);
1173 exceptions_throw_illegalaccessexception(u);
1175 return resolveFailed; /* exception */
1178 /* for non-static methods we have to check the constraints on the */
1182 typeinfo_t *insttip;
1185 /* The instanceslot must contain a reference to a non-array type */
1187 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1188 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1189 return resolveFailed;
1191 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1192 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1193 return resolveFailed;
1196 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1198 /* The instruction writes a field in an uninitialized object. */
1199 /* This is only allowed when a field of an uninitialized 'this' object is */
1200 /* written inside an initialization method */
1202 classinfo *initclass;
1203 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1206 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1207 return resolveFailed;
1210 /* XXX check that class of field == refmethod->clazz */
1211 initclass = referer; /* XXX classrefs */
1212 assert(initclass->state & CLASS_LINKED);
1214 typeinfo_init_classinfo(&tinfo, initclass);
1218 insttip = instanceti;
1221 result = resolve_lazy_subtype_checks(refmethod,
1223 CLASSREF_OR_CLASSINFO(container),
1224 resolveLinkageError);
1225 if (result != resolveSucceeded)
1228 /* check protected access */
1230 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1232 result = resolve_lazy_subtype_checks(refmethod,
1234 CLASSREF_OR_CLASSINFO(referer),
1235 resolveIllegalAccessError);
1236 if (result != resolveSucceeded)
1242 /* for PUT* instructions we have to check the constraints on the value type */
1245 assert(fieldtyperef);
1247 /* check subtype constraints */
1248 result = resolve_lazy_subtype_checks(refmethod,
1250 CLASSREF_OR_CLASSINFO(fieldtyperef),
1251 resolveLinkageError);
1253 if (result != resolveSucceeded)
1257 /* impose loading constraint on field type */
1259 if (fi->type == TYPE_ADR) {
1260 assert(fieldtyperef);
1261 if (!classcache_add_constraint(declarer->classloader,
1262 referer->classloader,
1263 fieldtyperef->name))
1264 return resolveFailed;
1267 /* XXX impose loading constraint on instance? */
1270 return resolveSucceeded;
1272 #endif /* defined(ENABLE_VERIFIER) */
1274 /* resolve_field_lazy **********************************************************
1276 Resolve an unresolved field reference lazily
1278 NOTE: This function does NOT do any verification checks. In case of a
1279 successful resolution, you must call resolve_field_verifier_checks
1280 in order to perform the necessary checks!
1283 refmethod........the referer method
1284 fieldref.........the field reference
1287 resolveSucceeded.....the reference has been resolved
1288 resolveDeferred......the resolving could not be performed lazily
1289 resolveFailed........resolving failed, an exception has been thrown.
1291 *******************************************************************************/
1293 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1294 constant_FMIref *fieldref)
1297 classinfo *container;
1302 /* the class containing the reference */
1304 referer = refmethod->clazz;
1307 /* check if the field itself is already resolved */
1309 if (IS_FMIREF_RESOLVED(fieldref))
1310 return resolveSucceeded;
1312 /* first we must resolve the class containg the field */
1314 /* XXX can/may lazyResolving trigger linking? */
1316 if (!resolve_class_from_name(referer, refmethod,
1317 fieldref->p.classref->name, resolveLazy, true, true, &container))
1319 /* the class reference could not be resolved */
1320 return resolveFailed; /* exception */
1323 return resolveDeferred; /* be lazy */
1325 assert(container->state & CLASS_LINKED);
1327 /* now we must find the declaration of the field in `container`
1328 * or one of its superclasses */
1330 fi = class_resolvefield(container,
1331 fieldref->name, fieldref->descriptor,
1334 /* The field does not exist. But since we were called lazily, */
1335 /* this error must not be reported now. (It will be reported */
1336 /* if eager resolving of this field is ever tried.) */
1338 exceptions_clear_exception();
1339 return resolveDeferred; /* be lazy */
1342 /* cache the result of the resolution */
1344 fieldref->p.field = fi;
1347 return resolveSucceeded;
1350 /* resolve_field ***************************************************************
1352 Resolve an unresolved field reference
1355 ref..............struct containing the reference
1356 mode.............mode of resolution:
1357 resolveLazy...only resolve if it does not
1358 require loading classes
1359 resolveEager..load classes if necessary
1362 *result..........set to the result of resolution, or to NULL if
1363 the reference has not been resolved
1364 In the case of an exception, *result is
1365 guaranteed to be set to NULL.
1368 true.............everything ok
1369 (*result may still be NULL for resolveLazy)
1370 false............an exception has been thrown
1372 *******************************************************************************/
1374 bool resolve_field(unresolved_field *ref,
1375 resolve_mode_t mode,
1379 classinfo *container;
1380 classinfo *declarer;
1381 constant_classref *fieldtyperef;
1383 resolve_result_t checkresult;
1387 assert(mode == resolveLazy || mode == resolveEager);
1391 #ifdef RESOLVE_VERBOSE
1392 unresolved_field_debug_dump(ref,stdout);
1395 /* the class containing the reference */
1397 referer = ref->referermethod->clazz;
1400 /* check if the field itself is already resolved */
1401 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1402 fi = ref->fieldref->p.field;
1403 container = fi->clazz;
1404 goto resolved_the_field;
1407 /* first we must resolve the class containg the field */
1408 if (!resolve_class_from_name(referer,ref->referermethod,
1409 ref->fieldref->p.classref->name,mode,true,true,&container))
1411 /* the class reference could not be resolved */
1412 return false; /* exception */
1415 return true; /* be lazy */
1418 assert(container->state & CLASS_LOADED);
1419 assert(container->state & CLASS_LINKED);
1421 /* now we must find the declaration of the field in `container`
1422 * or one of its superclasses */
1424 #ifdef RESOLVE_VERBOSE
1425 printf(" resolving field in class...\n");
1428 fi = class_resolvefield(container,
1429 ref->fieldref->name,ref->fieldref->descriptor,
1432 if (mode == resolveLazy) {
1433 /* The field does not exist. But since we were called lazily, */
1434 /* this error must not be reported now. (It will be reported */
1435 /* if eager resolving of this field is ever tried.) */
1437 exceptions_clear_exception();
1438 return true; /* be lazy */
1441 return false; /* exception */
1444 /* cache the result of the resolution */
1445 ref->fieldref->p.field = fi;
1449 #ifdef ENABLE_VERIFIER
1450 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1451 /* that no missing parts of an instruction will be accessed. */
1453 checkresult = resolve_field_verifier_checks(
1458 NULL, /* instanceti, handled by constraints below */
1459 NULL, /* valueti, handled by constraints below */
1460 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1461 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1463 if (checkresult != resolveSucceeded)
1464 return (bool) checkresult;
1466 declarer = fi->clazz;
1468 assert(declarer->state & CLASS_LOADED);
1469 assert(declarer->state & CLASS_LINKED);
1471 /* for non-static accesses we have to check the constraints on the */
1474 if (!(ref->flags & RESOLVE_STATIC)) {
1475 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1476 &(ref->instancetypes),
1477 CLASSREF_OR_CLASSINFO(container),
1478 mode, resolveLinkageError);
1479 if (checkresult != resolveSucceeded)
1480 return (bool) checkresult;
1483 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1485 /* for PUT* instructions we have to check the constraints on the value type */
1486 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1487 assert(fieldtyperef);
1488 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1489 /* check subtype constraints */
1490 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1491 &(ref->valueconstraints),
1492 CLASSREF_OR_CLASSINFO(fieldtyperef),
1493 mode, resolveLinkageError);
1494 if (checkresult != resolveSucceeded)
1495 return (bool) checkresult;
1499 /* check protected access */
1500 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1501 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1502 &(ref->instancetypes),
1503 CLASSREF_OR_CLASSINFO(referer),
1505 resolveIllegalAccessError);
1506 if (checkresult != resolveSucceeded)
1507 return (bool) checkresult;
1511 #endif /* ENABLE_VERIFIER */
1519 /* resolve_field_eager *********************************************************
1521 Resolve an unresolved field reference eagerly.
1524 ref..............struct containing the reference
1527 fieldinfo * to the field, or
1528 NULL if an exception has been thrown
1530 *******************************************************************************/
1532 fieldinfo * resolve_field_eager(unresolved_field *ref)
1536 if (!resolve_field(ref,resolveEager,&fi))
1542 /******************************************************************************/
1543 /* METHOD RESOLUTION */
1544 /******************************************************************************/
1546 /* resolve_method_invokespecial_lookup *****************************************
1548 Do the special lookup for methods invoked by INVOKESPECIAL
1551 refmethod........the method containing the reference
1552 mi...............the methodinfo of the resolved method
1555 a methodinfo *...the result of the lookup,
1556 NULL.............an exception has been thrown
1558 *******************************************************************************/
1560 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1563 classinfo *declarer;
1569 /* get referer and declarer classes */
1571 referer = refmethod->clazz;
1574 declarer = mi->clazz;
1576 assert(referer->state & CLASS_LINKED);
1578 /* checks for INVOKESPECIAL: */
1579 /* for <init> and methods of the current class we don't need any */
1580 /* special checks. Otherwise we must verify that the called method */
1581 /* belongs to a super class of the current class */
1583 if ((referer != declarer) && (mi->name != utf_init)) {
1584 /* check that declarer is a super class of the current class */
1586 if (!class_issubclass(referer,declarer)) {
1587 exceptions_throw_verifyerror(refmethod,
1588 "INVOKESPECIAL calling non-super class method");
1592 /* if the referer has ACC_SUPER set, we must do the special */
1593 /* lookup starting with the direct super class of referer */
1595 if ((referer->flags & ACC_SUPER) != 0) {
1596 mi = class_resolvemethod(referer->super,
1601 /* the spec calls for an AbstractMethodError in this case */
1603 exceptions_throw_abstractmethoderror();
1614 /* resolve_method_verifier_checks ******************************************
1616 Do the verifier checks necessary after a method has been resolved.
1619 refmethod........the method containing the reference
1620 methodref........the method reference
1621 mi...............the methodinfo of the resolved method
1622 invokestatic.....true if the method is invoked by INVOKESTATIC
1625 resolveSucceeded....everything ok
1626 resolveDeferred.....tests could not be done, have been deferred
1627 resolveFailed.......exception has been thrown
1629 *******************************************************************************/
1631 #if defined(ENABLE_VERIFIER)
1632 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1633 constant_FMIref *methodref,
1637 classinfo *declarer;
1647 #ifdef RESOLVE_VERBOSE
1648 printf("resolve_method_verifier_checks\n");
1649 printf(" flags: %02x\n",mi->flags);
1652 /* get the classinfos and the method descriptor */
1654 referer = refmethod->clazz;
1657 declarer = mi->clazz;
1662 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1663 /* a static method is accessed via an instance, or vice versa */
1664 exceptions_throw_incompatibleclasschangeerror(declarer,
1665 (mi->flags & ACC_STATIC)
1666 ? "static method called via instance"
1667 : "instance method called without instance");
1669 return resolveFailed;
1672 /* check access rights */
1674 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1675 /* XXX clean this up. this should be in exceptions.c */
1678 utf_bytes(declarer->name) +
1679 utf_bytes(mi->name) +
1680 utf_bytes(mi->descriptor) +
1681 utf_bytes(referer->name) +
1684 msg = MNEW(char, msglen);
1686 strcpy(msg, "method is not accessible (");
1687 utf_cat_classname(msg, declarer->name);
1689 utf_cat(msg, mi->name);
1690 utf_cat(msg, mi->descriptor);
1691 strcat(msg, " from ");
1692 utf_cat_classname(msg, referer->name);
1695 u = utf_new_char(msg);
1697 MFREE(msg, char, msglen);
1699 exceptions_throw_illegalaccessexception(u);
1701 return resolveFailed; /* exception */
1706 return resolveSucceeded;
1708 #endif /* defined(ENABLE_VERIFIER) */
1711 /* resolve_method_instance_type_checks *****************************************
1713 Check the instance type of a method invocation.
1716 refmethod........the method containing the reference
1717 mi...............the methodinfo of the resolved method
1718 instanceti.......typeinfo of the instance slot
1719 invokespecial....true if the method is invoked by INVOKESPECIAL
1722 resolveSucceeded....everything ok
1723 resolveDeferred.....tests could not be done, have been deferred
1724 resolveFailed.......exception has been thrown
1726 *******************************************************************************/
1728 #if defined(ENABLE_VERIFIER)
1729 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1731 typeinfo_t *instanceti,
1736 resolve_result_t result;
1738 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1739 { /* XXX clean up */
1740 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1741 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1742 : CLASSREF_OR_CLASSINFO(refmethod->clazz);
1744 if (!typeinfo_init_class(tip, initclass))
1745 return resolveFailed;
1751 result = resolve_lazy_subtype_checks(refmethod,
1753 CLASSREF_OR_CLASSINFO(mi->clazz),
1754 resolveLinkageError);
1755 if (result != resolveSucceeded)
1758 /* check protected access */
1760 /* XXX use other `declarer` than mi->clazz? */
1761 if (((mi->flags & ACC_PROTECTED) != 0)
1762 && !SAME_PACKAGE(mi->clazz, refmethod->clazz))
1764 result = resolve_lazy_subtype_checks(refmethod,
1766 CLASSREF_OR_CLASSINFO(refmethod->clazz),
1767 resolveIllegalAccessError);
1768 if (result != resolveSucceeded)
1774 return resolveSucceeded;
1776 #endif /* defined(ENABLE_VERIFIER) */
1779 /* resolve_method_param_type_checks ********************************************
1781 Check non-instance parameter types of a method invocation.
1784 jd...............jitdata of the method doing the call
1785 refmethod........the method containing the reference
1786 iptr.............the invoke instruction
1787 mi...............the methodinfo of the resolved method
1788 invokestatic.....true if the method is invoked by INVOKESTATIC
1791 resolveSucceeded....everything ok
1792 resolveDeferred.....tests could not be done, have been deferred
1793 resolveFailed.......exception has been thrown
1795 *******************************************************************************/
1797 #if defined(ENABLE_VERIFIER)
1798 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1799 methodinfo *refmethod,
1805 resolve_result_t result;
1807 typedesc *paramtypes;
1814 instancecount = (invokestatic) ? 0 : 1;
1816 /* check subtype constraints for TYPE_ADR parameters */
1818 md = mi->parseddesc;
1819 paramtypes = md->paramtypes;
1821 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1822 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1823 type = md->paramtypes[i+instancecount].type;
1826 assert(type == param->type);
1828 if (type == TYPE_ADR) {
1829 result = resolve_lazy_subtype_checks(refmethod,
1831 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1832 resolveLinkageError);
1833 if (result != resolveSucceeded)
1840 return resolveSucceeded;
1842 #endif /* defined(ENABLE_VERIFIER) */
1845 /* resolve_method_param_type_checks_stackbased *********************************
1847 Check non-instance parameter types of a method invocation.
1850 refmethod........the method containing the reference
1851 mi...............the methodinfo of the resolved method
1852 invokestatic.....true if the method is invoked by INVOKESTATIC
1853 stack............TOS before the INVOKE instruction
1856 resolveSucceeded....everything ok
1857 resolveDeferred.....tests could not be done, have been deferred
1858 resolveFailed.......exception has been thrown
1860 *******************************************************************************/
1862 #if defined(ENABLE_VERIFIER)
1863 resolve_result_t resolve_method_param_type_checks_stackbased(
1864 methodinfo *refmethod,
1867 typedescriptor_t *stack)
1869 typedescriptor_t *param;
1870 resolve_result_t result;
1872 typedesc *paramtypes;
1877 instancecount = (invokestatic) ? 0 : 1;
1879 /* check subtype constraints for TYPE_ADR parameters */
1881 md = mi->parseddesc;
1882 paramtypes = md->paramtypes;
1884 param = stack - (md->paramslots - 1 - instancecount);
1886 for (i = instancecount; i < md->paramcount; ++i) {
1887 type = md->paramtypes[i].type;
1889 assert(type == param->type);
1891 if (type == TYPE_ADR) {
1892 result = resolve_lazy_subtype_checks(refmethod,
1894 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1895 resolveLinkageError);
1896 if (result != resolveSucceeded)
1900 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1905 return resolveSucceeded;
1907 #endif /* defined(ENABLE_VERIFIER) */
1910 /* resolve_method_loading_constraints ******************************************
1912 Impose loading constraints on the parameters and return type of the
1916 referer..........the class refering to the method
1917 mi...............the method
1920 true................everything ok
1921 false...............an exception has been thrown
1923 *******************************************************************************/
1925 #if defined(ENABLE_VERIFIER)
1926 bool resolve_method_loading_constraints(classinfo *referer,
1930 typedesc *paramtypes;
1935 /* impose loading constraints on parameters (including instance) */
1937 md = mi->parseddesc;
1938 paramtypes = md->paramtypes;
1939 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1941 for (i = 0; i < md->paramcount; i++) {
1942 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1943 if (i < instancecount) {
1944 /* The type of the 'this' pointer is the class containing */
1945 /* the method definition. Since container is the same as, */
1946 /* or a subclass of declarer, we also constrain declarer */
1947 /* by transitivity of loading constraints. */
1948 name = mi->clazz->name;
1951 name = paramtypes[i].classref->name;
1954 /* The caller (referer) and the callee (container) must agree */
1955 /* on the types of the parameters. */
1956 if (!classcache_add_constraint(referer->classloader,
1957 mi->clazz->classloader, name))
1958 return false; /* exception */
1962 /* impose loading constraint onto return type */
1964 if (md->returntype.type == TYPE_ADR) {
1965 /* The caller (referer) and the callee (container) must agree */
1966 /* on the return type. */
1967 if (!classcache_add_constraint(referer->classloader,
1968 mi->clazz->classloader,
1969 md->returntype.classref->name))
1970 return false; /* exception */
1977 #endif /* defined(ENABLE_VERIFIER) */
1980 /* resolve_method_lazy *********************************************************
1982 Resolve an unresolved method reference lazily
1984 NOTE: This function does NOT do any verification checks. In case of a
1985 successful resolution, you must call resolve_method_verifier_checks
1986 in order to perform the necessary checks!
1989 refmethod........the referer method
1990 methodref........the method reference
1991 invokespecial....true if this is an INVOKESPECIAL instruction
1994 resolveSucceeded.....the reference has been resolved
1995 resolveDeferred......the resolving could not be performed lazily
1996 resolveFailed........resolving failed, an exception has been thrown.
1998 *******************************************************************************/
2000 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
2001 constant_FMIref *methodref,
2005 classinfo *container;
2010 #ifdef RESOLVE_VERBOSE
2011 printf("resolve_method_lazy\n");
2014 /* the class containing the reference */
2016 referer = refmethod->clazz;
2019 /* check if the method itself is already resolved */
2021 if (IS_FMIREF_RESOLVED(methodref))
2022 return resolveSucceeded;
2024 /* first we must resolve the class containg the method */
2026 if (!resolve_class_from_name(referer, refmethod,
2027 methodref->p.classref->name, resolveLazy, true, true, &container))
2029 /* the class reference could not be resolved */
2030 return resolveFailed; /* exception */
2033 return resolveDeferred; /* be lazy */
2035 assert(container->state & CLASS_LINKED);
2037 /* now we must find the declaration of the method in `container`
2038 * or one of its superclasses */
2040 if (container->flags & ACC_INTERFACE) {
2041 mi = class_resolveinterfacemethod(container,
2043 methodref->descriptor,
2047 mi = class_resolveclassmethod(container,
2049 methodref->descriptor,
2054 /* The method does not exist. But since we were called lazily, */
2055 /* this error must not be reported now. (It will be reported */
2056 /* if eager resolving of this method is ever tried.) */
2058 exceptions_clear_exception();
2059 return resolveDeferred; /* be lazy */
2062 if (invokespecial) {
2063 mi = resolve_method_invokespecial_lookup(refmethod, mi);
2065 return resolveFailed; /* exception */
2068 /* have the method params already been parsed? no, do it. */
2070 if (!mi->parseddesc->params)
2071 descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
2073 /* cache the result of the resolution */
2075 methodref->p.method = mi;
2079 return resolveSucceeded;
2082 /* resolve_method **************************************************************
2084 Resolve an unresolved method reference
2087 ref..............struct containing the reference
2088 mode.............mode of resolution:
2089 resolveLazy...only resolve if it does not
2090 require loading classes
2091 resolveEager..load classes if necessary
2094 *result..........set to the result of resolution, or to NULL if
2095 the reference has not been resolved
2096 In the case of an exception, *result is
2097 guaranteed to be set to NULL.
2100 true.............everything ok
2101 (*result may still be NULL for resolveLazy)
2102 false............an exception has been thrown
2104 *******************************************************************************/
2106 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2109 classinfo *container;
2110 classinfo *declarer;
2112 typedesc *paramtypes;
2115 resolve_result_t checkresult;
2119 assert(mode == resolveLazy || mode == resolveEager);
2121 #ifdef RESOLVE_VERBOSE
2122 unresolved_method_debug_dump(ref,stdout);
2127 /* the class containing the reference */
2129 referer = ref->referermethod->clazz;
2132 /* check if the method itself is already resolved */
2134 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2135 mi = ref->methodref->p.method;
2136 container = mi->clazz;
2137 goto resolved_the_method;
2140 /* first we must resolve the class containing the method */
2142 if (!resolve_class_from_name(referer,ref->referermethod,
2143 ref->methodref->p.classref->name,mode,true,true,&container))
2145 /* the class reference could not be resolved */
2146 return false; /* exception */
2149 return true; /* be lazy */
2152 assert(container->state & CLASS_LINKED);
2154 /* now we must find the declaration of the method in `container`
2155 * or one of its superclasses */
2157 if (container->flags & ACC_INTERFACE) {
2158 mi = class_resolveinterfacemethod(container,
2159 ref->methodref->name,
2160 ref->methodref->descriptor,
2164 mi = class_resolveclassmethod(container,
2165 ref->methodref->name,
2166 ref->methodref->descriptor,
2171 if (mode == resolveLazy) {
2172 /* The method does not exist. But since we were called lazily, */
2173 /* this error must not be reported now. (It will be reported */
2174 /* if eager resolving of this method is ever tried.) */
2176 exceptions_clear_exception();
2177 return true; /* be lazy */
2180 return false; /* exception */ /* XXX set exceptionptr? */
2183 /* { the method reference has been resolved } */
2185 if (ref->flags & RESOLVE_SPECIAL) {
2186 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2188 return false; /* exception */
2191 /* have the method params already been parsed? no, do it. */
2193 if (!mi->parseddesc->params)
2194 descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
2196 /* cache the resolution */
2198 ref->methodref->p.method = mi;
2200 resolved_the_method:
2202 #ifdef ENABLE_VERIFIER
2205 checkresult = resolve_method_verifier_checks(
2209 (ref->flags & RESOLVE_STATIC));
2211 if (checkresult != resolveSucceeded)
2212 return (bool) checkresult;
2214 /* impose loading constraints on params and return type */
2216 if (!resolve_method_loading_constraints(referer, mi))
2219 declarer = mi->clazz;
2221 assert(referer->state & CLASS_LINKED);
2223 /* for non-static methods we have to check the constraints on the */
2226 if (!(ref->flags & RESOLVE_STATIC)) {
2227 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2228 &(ref->instancetypes),
2229 CLASSREF_OR_CLASSINFO(container),
2231 resolveLinkageError);
2232 if (checkresult != resolveSucceeded)
2233 return (bool) checkresult;
2240 /* check subtype constraints for TYPE_ADR parameters */
2242 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2243 paramtypes = mi->parseddesc->paramtypes;
2245 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2246 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2247 if (ref->paramconstraints) {
2248 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2249 ref->paramconstraints + i,
2250 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2252 resolveLinkageError);
2253 if (checkresult != resolveSucceeded)
2254 return (bool) checkresult;
2259 /* check protected access */
2261 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2263 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2264 &(ref->instancetypes),
2265 CLASSREF_OR_CLASSINFO(referer),
2267 resolveIllegalAccessError);
2268 if (checkresult != resolveSucceeded)
2269 return (bool) checkresult;
2272 #endif /* ENABLE_VERIFIER */
2279 /* resolve_method_eager ********************************************************
2281 Resolve an unresolved method reference eagerly.
2284 ref..............struct containing the reference
2287 methodinfo * to the method, or
2288 NULL if an exception has been thrown
2290 *******************************************************************************/
2292 methodinfo * resolve_method_eager(unresolved_method *ref)
2296 if (!resolve_method(ref,resolveEager,&mi))
2302 /******************************************************************************/
2303 /* CREATING THE DATA STRUCTURES */
2304 /******************************************************************************/
2306 #ifdef ENABLE_VERIFIER
2307 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2308 methodinfo *refmethod,
2309 unresolved_subtype_set *stset,
2311 utf *declaredclassname)
2319 #ifdef RESOLVE_VERBOSE
2320 printf("unresolved_subtype_set_from_typeinfo\n");
2321 #ifdef TYPEINFO_DEBUG
2322 typeinfo_print(stdout,tinfo,4);
2324 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2328 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2329 exceptions_throw_verifyerror(refmethod,
2330 "Invalid use of returnAddress");
2334 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2335 exceptions_throw_verifyerror(refmethod,
2336 "Invalid use of uninitialized object");
2340 /* the nulltype is always assignable */
2341 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2344 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2345 if (declaredclassname == utf_java_lang_Object
2346 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2351 if (tinfo->merged) {
2352 count = tinfo->merged->count;
2353 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2354 for (i=0; i<count; ++i) {
2355 classref_or_classinfo c = tinfo->merged->list[i];
2356 if (tinfo->dimension > 0) {
2357 /* a merge of array types */
2358 /* the merged list contains the possible _element_ types, */
2359 /* so we have to create array types with these elements. */
2360 if (IS_CLASSREF(c)) {
2361 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2364 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2367 stset->subtyperefs[i] = c;
2369 stset->subtyperefs[count].any = NULL; /* terminate */
2372 if ((IS_CLASSREF(tinfo->typeclass)
2373 ? tinfo->typeclass.ref->name
2374 : tinfo->typeclass.cls->name) == declaredclassname)
2376 /* the class names are the same */
2377 /* equality is guaranteed by the loading constraints */
2381 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2382 stset->subtyperefs[0] = tinfo->typeclass;
2383 stset->subtyperefs[1].any = NULL; /* terminate */
2390 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2393 #endif /* ENABLE_VERIFIER */
2395 /* create_unresolved_class *****************************************************
2397 Create an unresolved_class struct for the given class reference
2400 refmethod........the method triggering the resolution (if any)
2401 classref.........the class reference
2402 valuetype........value type to check against the resolved class
2403 may be NULL, if no typeinfo is available
2406 a pointer to a new unresolved_class struct, or
2407 NULL if an exception has been thrown
2409 *******************************************************************************/
2411 #ifdef ENABLE_VERIFIER
2412 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2413 constant_classref *classref,
2414 typeinfo_t *valuetype)
2416 unresolved_class *ref;
2418 #ifdef RESOLVE_VERBOSE
2419 printf("create_unresolved_class\n");
2420 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->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);
2425 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2428 ref = NEW(unresolved_class);
2429 ref->classref = classref;
2430 ref->referermethod = refmethod;
2433 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2434 &(ref->subtypeconstraints),valuetype,classref->name))
2438 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2443 #endif /* ENABLE_VERIFIER */
2445 /* resolve_create_unresolved_field *********************************************
2447 Create an unresolved_field struct for the given field access instruction
2450 referer..........the class containing the reference
2451 refmethod........the method triggering the resolution (if any)
2452 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2455 a pointer to a new unresolved_field struct, or
2456 NULL if an exception has been thrown
2458 *******************************************************************************/
2460 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2461 methodinfo *refmethod,
2464 unresolved_field *ref;
2465 constant_FMIref *fieldref = NULL;
2467 #ifdef RESOLVE_VERBOSE
2468 printf("create_unresolved_field\n");
2469 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2470 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2471 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2474 ref = NEW(unresolved_field);
2476 ref->referermethod = refmethod;
2477 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2479 switch (iptr->opc) {
2481 ref->flags |= RESOLVE_PUTFIELD;
2484 case ICMD_PUTFIELDCONST:
2485 ref->flags |= RESOLVE_PUTFIELD;
2488 case ICMD_PUTSTATIC:
2489 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2492 case ICMD_PUTSTATICCONST:
2493 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2499 case ICMD_GETSTATIC:
2500 ref->flags |= RESOLVE_STATIC;
2503 #if !defined(NDEBUG)
2509 fieldref = iptr->sx.s23.s3.fmiref;
2513 #ifdef RESOLVE_VERBOSE
2514 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2515 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2516 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2517 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2521 ref->fieldref = fieldref;
2526 /* resolve_constrain_unresolved_field ******************************************
2528 Record subtype constraints for a field access.
2531 ref..............the unresolved_field structure of the access
2532 referer..........the class containing the reference
2533 refmethod........the method triggering the resolution (if any)
2534 instanceti.......instance typeinfo, if available
2535 valueti..........value typeinfo, if available
2538 true.............everything ok
2539 false............an exception has been thrown
2541 *******************************************************************************/
2543 #if defined(ENABLE_VERIFIER)
2544 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2546 methodinfo *refmethod,
2547 typeinfo_t *instanceti,
2548 typeinfo_t *valueti)
2550 constant_FMIref *fieldref;
2557 fieldref = ref->fieldref;
2560 #ifdef RESOLVE_VERBOSE
2561 printf("constrain_unresolved_field\n");
2562 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2563 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2564 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2565 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2566 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2567 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2568 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2572 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2573 fd = fieldref->parseddesc.fd;
2576 /* record subtype constraints for the instance type, if any */
2578 typeinfo_t *insttip;
2580 /* The instanceslot must contain a reference to a non-array type */
2581 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2582 exceptions_throw_verifyerror(refmethod,
2583 "illegal instruction: field access on non-reference");
2586 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2587 exceptions_throw_verifyerror(refmethod,
2588 "illegal instruction: field access on array");
2592 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2593 TYPEINFO_IS_NEWOBJECT(*instanceti))
2595 /* The instruction writes a field in an uninitialized object. */
2596 /* This is only allowed when a field of an uninitialized 'this' object is */
2597 /* written inside an initialization method */
2599 classinfo *initclass;
2600 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2603 exceptions_throw_verifyerror(refmethod,
2604 "accessing field of uninitialized object");
2607 /* XXX check that class of field == refmethod->clazz */
2608 initclass = refmethod->clazz; /* XXX classrefs */
2609 assert(initclass->state & CLASS_LOADED);
2610 assert(initclass->state & CLASS_LINKED);
2612 typeinfo_init_classinfo(&tinfo, initclass);
2616 insttip = instanceti;
2618 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2619 &(ref->instancetypes), insttip,
2620 FIELDREF_CLASSNAME(fieldref)))
2624 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2627 /* record subtype constraints for the value type, if any */
2629 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2631 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2632 &(ref->valueconstraints), valueti,
2633 fieldref->parseddesc.fd->classref->name))
2637 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2642 #endif /* ENABLE_VERIFIER */
2644 /* resolve_create_unresolved_method ********************************************
2646 Create an unresolved_method struct for the given method invocation
2649 referer..........the class containing the reference
2650 refmethod........the method triggering the resolution (if any)
2651 iptr.............the INVOKE* instruction
2654 a pointer to a new unresolved_method struct
2656 *******************************************************************************/
2658 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2659 methodinfo *refmethod,
2660 constant_FMIref *methodref,
2664 unresolved_method *ref;
2668 #ifdef RESOLVE_VERBOSE
2669 printf("create_unresolved_method\n");
2670 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2671 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2672 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2673 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2674 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2677 /* allocate params if necessary */
2678 if (!methodref->parseddesc.md->params)
2679 descriptor_params_from_paramtypes(
2680 methodref->parseddesc.md,
2681 (invokestatic) ? ACC_STATIC : ACC_NONE);
2683 /* create the data structure */
2684 ref = NEW(unresolved_method);
2685 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2686 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2687 ref->referermethod = refmethod;
2688 ref->methodref = methodref;
2689 ref->paramconstraints = NULL;
2690 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2696 /* resolve_constrain_unresolved_method_instance ********************************
2698 Record subtype constraints for the instance argument of a method call.
2701 ref..............the unresolved_method structure of the call
2702 referer..........the class containing the reference
2703 refmethod........the method triggering the resolution (if any)
2704 iptr.............the INVOKE* instruction
2707 true.............everything ok
2708 false............an exception has been thrown
2710 *******************************************************************************/
2712 #if defined(ENABLE_VERIFIER)
2713 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2714 methodinfo *refmethod,
2715 typeinfo_t *instanceti,
2718 constant_FMIref *methodref;
2719 constant_classref *instanceref;
2724 methodref = ref->methodref;
2727 /* XXX clean this up */
2728 instanceref = IS_FMIREF_RESOLVED(methodref)
2729 ? class_get_self_classref(methodref->p.method->clazz)
2730 : methodref->p.classref;
2732 #ifdef RESOLVE_VERBOSE
2733 printf("resolve_constrain_unresolved_method_instance\n");
2734 printf(" rmethod: "); method_println(refmethod);
2735 printf(" mref : "); method_methodref_println(methodref);
2738 /* record subtype constraints for the instance type, if any */
2740 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2741 { /* XXX clean up */
2742 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2743 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2744 : CLASSREF_OR_CLASSINFO(refmethod->clazz);
2746 if (!typeinfo_init_class(tip, initclass))
2753 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2754 &(ref->instancetypes),tip,instanceref->name))
2759 #endif /* defined(ENABLE_VERIFIER) */
2762 /* resolve_constrain_unresolved_method_params *********************************
2764 Record subtype constraints for the non-instance arguments of a method call.
2767 jd...............current jitdata (for looking up variables)
2768 ref..............the unresolved_method structure of the call
2769 refmethod........the method triggering the resolution (if any)
2770 iptr.............the INVOKE* instruction
2773 true.............everything ok
2774 false............an exception has been thrown
2776 *******************************************************************************/
2778 #if defined(ENABLE_VERIFIER)
2779 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2780 unresolved_method *ref,
2781 methodinfo *refmethod,
2784 constant_FMIref *methodref;
2792 methodref = ref->methodref;
2794 md = methodref->parseddesc.md;
2796 assert(md->params != NULL);
2798 #ifdef RESOLVE_VERBOSE
2799 printf("resolve_constrain_unresolved_method_params\n");
2800 printf(" rmethod: "); method_println(refmethod);
2801 printf(" mref : "); method_methodref_println(methodref);
2804 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2806 /* record subtype constraints for the parameter types, if any */
2808 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2809 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2810 type = md->paramtypes[i+instancecount].type;
2813 assert(type == param->type);
2815 if (type == TYPE_ADR) {
2816 if (!ref->paramconstraints) {
2817 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2818 for (j=md->paramcount-1-instancecount; j>i; --j)
2819 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2821 assert(ref->paramconstraints);
2822 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2823 ref->paramconstraints + i,&(param->typeinfo),
2824 md->paramtypes[i+instancecount].classref->name))
2828 if (ref->paramconstraints)
2829 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2835 #endif /* ENABLE_VERIFIER */
2838 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2840 Record subtype constraints for the non-instance arguments of a method call.
2843 ref..............the unresolved_method structure of the call
2844 refmethod........the method triggering the resolution (if any)
2845 stack............TOS before the INVOKE instruction
2848 true.............everything ok
2849 false............an exception has been thrown
2851 *******************************************************************************/
2853 #if defined(ENABLE_VERIFIER)
2854 bool resolve_constrain_unresolved_method_params_stackbased(
2855 unresolved_method *ref,
2856 methodinfo *refmethod,
2857 typedescriptor_t *stack)
2859 constant_FMIref *methodref;
2860 typedescriptor_t *param;
2867 methodref = ref->methodref;
2869 md = methodref->parseddesc.md;
2871 assert(md->params != NULL);
2873 #ifdef RESOLVE_VERBOSE
2874 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2875 printf(" rmethod: "); method_println(refmethod);
2876 printf(" mref : "); method_methodref_println(methodref);
2879 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2881 /* record subtype constraints for the parameter types, if any */
2883 param = stack - (md->paramslots - 1 - instancecount);
2885 for (i = instancecount; i < md->paramcount; ++i) {
2886 type = md->paramtypes[i].type;
2888 assert(type == param->type);
2890 if (type == TYPE_ADR) {
2891 if (!ref->paramconstraints) {
2892 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2893 for (j = 0; j < i - instancecount; ++j)
2894 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2896 assert(ref->paramconstraints);
2897 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2898 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2899 md->paramtypes[i].classref->name))
2903 if (ref->paramconstraints)
2904 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2907 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2912 #endif /* ENABLE_VERIFIER */
2915 /******************************************************************************/
2916 /* FREEING MEMORY */
2917 /******************************************************************************/
2919 #ifdef ENABLE_VERIFIER
2920 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2923 classref_or_classinfo *p = list;
2925 /* this is silly. we *only* need to count the elements for MFREE */
2928 MFREE(list,classref_or_classinfo,(p - list));
2931 #endif /* ENABLE_VERIFIER */
2933 /* unresolved_class_free *******************************************************
2935 Free the memory used by an unresolved_class
2938 ref..............the unresolved_class
2940 *******************************************************************************/
2942 void unresolved_class_free(unresolved_class *ref)
2946 #ifdef ENABLE_VERIFIER
2947 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2949 FREE(ref,unresolved_class);
2952 /* unresolved_field_free *******************************************************
2954 Free the memory used by an unresolved_field
2957 ref..............the unresolved_field
2959 *******************************************************************************/
2961 void unresolved_field_free(unresolved_field *ref)
2965 #ifdef ENABLE_VERIFIER
2966 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2967 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2969 FREE(ref,unresolved_field);
2972 /* unresolved_method_free ******************************************************
2974 Free the memory used by an unresolved_method
2977 ref..............the unresolved_method
2979 *******************************************************************************/
2981 void unresolved_method_free(unresolved_method *ref)
2985 #ifdef ENABLE_VERIFIER
2986 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2987 if (ref->paramconstraints) {
2989 int count = ref->methodref->parseddesc.md->paramcount;
2991 for (i=0; i<count; ++i)
2992 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2993 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2996 FREE(ref,unresolved_method);
2999 /******************************************************************************/
3001 /******************************************************************************/
3003 #if !defined(NDEBUG)
3005 /* unresolved_subtype_set_debug_dump *******************************************
3007 Print debug info for unresolved_subtype_set to stream
3010 stset............the unresolved_subtype_set
3011 file.............the stream
3013 *******************************************************************************/
3015 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
3017 classref_or_classinfo *p;
3019 if (SUBTYPESET_IS_EMPTY(*stset)) {
3020 fprintf(file," (empty)\n");
3023 p = stset->subtyperefs;
3024 for (;p->any; ++p) {
3025 if (IS_CLASSREF(*p)) {
3026 fprintf(file," ref: ");
3027 utf_fprint_printable_ascii(file,p->ref->name);
3030 fprintf(file," cls: ");
3031 utf_fprint_printable_ascii(file,p->cls->name);
3038 /* unresolved_class_debug_dump *************************************************
3040 Print debug info for unresolved_class to stream
3043 ref..............the unresolved_class
3044 file.............the stream
3046 *******************************************************************************/
3048 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3050 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3052 fprintf(file," referer : ");
3053 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3054 fprintf(file," refmethod : ");
3055 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3056 fprintf(file," refmethodd: ");
3057 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3058 fprintf(file," classname : ");
3059 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3060 fprintf(file," subtypeconstraints:\n");
3061 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3065 /* unresolved_field_debug_dump *************************************************
3067 Print debug info for unresolved_field to stream
3070 ref..............the unresolved_field
3071 file.............the stream
3073 *******************************************************************************/
3075 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3077 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3079 fprintf(file," referer : ");
3080 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3081 fprintf(file," refmethod : ");
3082 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3083 fprintf(file," refmethodd: ");
3084 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3085 fprintf(file," classname : ");
3086 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3087 fprintf(file," name : ");
3088 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3089 fprintf(file," descriptor: ");
3090 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3091 fprintf(file," parseddesc: ");
3092 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3093 fprintf(file," flags : %04x\n",ref->flags);
3094 fprintf(file," instancetypes:\n");
3095 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3096 fprintf(file," valueconstraints:\n");
3097 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3101 /* unresolved_method_debug_dump ************************************************
3103 Print debug info for unresolved_method to stream
3106 ref..............the unresolved_method
3107 file.............the stream
3109 *******************************************************************************/
3111 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3115 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3117 fprintf(file," referer : ");
3118 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3119 fprintf(file," refmethod : ");
3120 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3121 fprintf(file," refmethodd: ");
3122 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3123 fprintf(file," classname : ");
3124 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3125 fprintf(file," name : ");
3126 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3127 fprintf(file," descriptor: ");
3128 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3129 fprintf(file," parseddesc: ");
3130 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3131 fprintf(file," flags : %04x\n",ref->flags);
3132 fprintf(file," instancetypes:\n");
3133 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3134 fprintf(file," paramconstraints:\n");
3135 if (ref->paramconstraints) {
3136 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3137 fprintf(file," param %d:\n",i);
3138 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3142 fprintf(file," (empty)\n");
3146 #endif /* !defined(NDEBUG) */
3150 * These are local overrides for various environment variables in Emacs.
3151 * Please do not remove this and leave it at the end of the file, where
3152 * Emacs will automagically detect them.
3153 * ---------------------------------------------------------------------
3156 * indent-tabs-mode: t
3160 * vim:noexpandtab:sw=4:ts=4: