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 descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
2072 /* cache the result of the resolution */
2074 methodref->p.method = mi;
2078 return resolveSucceeded;
2081 /* resolve_method **************************************************************
2083 Resolve an unresolved method reference
2086 ref..............struct containing the reference
2087 mode.............mode of resolution:
2088 resolveLazy...only resolve if it does not
2089 require loading classes
2090 resolveEager..load classes if necessary
2093 *result..........set to the result of resolution, or to NULL if
2094 the reference has not been resolved
2095 In the case of an exception, *result is
2096 guaranteed to be set to NULL.
2099 true.............everything ok
2100 (*result may still be NULL for resolveLazy)
2101 false............an exception has been thrown
2103 *******************************************************************************/
2105 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2108 classinfo *container;
2109 classinfo *declarer;
2111 typedesc *paramtypes;
2114 resolve_result_t checkresult;
2118 assert(mode == resolveLazy || mode == resolveEager);
2120 #ifdef RESOLVE_VERBOSE
2121 unresolved_method_debug_dump(ref,stdout);
2126 /* the class containing the reference */
2128 referer = ref->referermethod->clazz;
2131 /* check if the method itself is already resolved */
2133 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2134 mi = ref->methodref->p.method;
2135 container = mi->clazz;
2136 goto resolved_the_method;
2139 /* first we must resolve the class containing the method */
2141 if (!resolve_class_from_name(referer,ref->referermethod,
2142 ref->methodref->p.classref->name,mode,true,true,&container))
2144 /* the class reference could not be resolved */
2145 return false; /* exception */
2148 return true; /* be lazy */
2151 assert(container->state & CLASS_LINKED);
2153 /* now we must find the declaration of the method in `container`
2154 * or one of its superclasses */
2156 if (container->flags & ACC_INTERFACE) {
2157 mi = class_resolveinterfacemethod(container,
2158 ref->methodref->name,
2159 ref->methodref->descriptor,
2163 mi = class_resolveclassmethod(container,
2164 ref->methodref->name,
2165 ref->methodref->descriptor,
2170 if (mode == resolveLazy) {
2171 /* The method does not exist. But since we were called lazily, */
2172 /* this error must not be reported now. (It will be reported */
2173 /* if eager resolving of this method is ever tried.) */
2175 exceptions_clear_exception();
2176 return true; /* be lazy */
2179 return false; /* exception */ /* XXX set exceptionptr? */
2182 /* { the method reference has been resolved } */
2184 if (ref->flags & RESOLVE_SPECIAL) {
2185 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2187 return false; /* exception */
2190 /* have the method params already been parsed? no, do it. */
2192 descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
2194 /* cache the resolution */
2196 ref->methodref->p.method = mi;
2198 resolved_the_method:
2200 #ifdef ENABLE_VERIFIER
2203 checkresult = resolve_method_verifier_checks(
2207 (ref->flags & RESOLVE_STATIC));
2209 if (checkresult != resolveSucceeded)
2210 return (bool) checkresult;
2212 /* impose loading constraints on params and return type */
2214 if (!resolve_method_loading_constraints(referer, mi))
2217 declarer = mi->clazz;
2219 assert(referer->state & CLASS_LINKED);
2221 /* for non-static methods we have to check the constraints on the */
2224 if (!(ref->flags & RESOLVE_STATIC)) {
2225 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2226 &(ref->instancetypes),
2227 CLASSREF_OR_CLASSINFO(container),
2229 resolveLinkageError);
2230 if (checkresult != resolveSucceeded)
2231 return (bool) checkresult;
2238 /* check subtype constraints for TYPE_ADR parameters */
2240 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2241 paramtypes = mi->parseddesc->paramtypes;
2243 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2244 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2245 if (ref->paramconstraints) {
2246 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2247 ref->paramconstraints + i,
2248 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2250 resolveLinkageError);
2251 if (checkresult != resolveSucceeded)
2252 return (bool) checkresult;
2257 /* check protected access */
2259 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2261 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2262 &(ref->instancetypes),
2263 CLASSREF_OR_CLASSINFO(referer),
2265 resolveIllegalAccessError);
2266 if (checkresult != resolveSucceeded)
2267 return (bool) checkresult;
2270 #endif /* ENABLE_VERIFIER */
2277 /* resolve_method_eager ********************************************************
2279 Resolve an unresolved method reference eagerly.
2282 ref..............struct containing the reference
2285 methodinfo * to the method, or
2286 NULL if an exception has been thrown
2288 *******************************************************************************/
2290 methodinfo * resolve_method_eager(unresolved_method *ref)
2294 if (!resolve_method(ref,resolveEager,&mi))
2300 /******************************************************************************/
2301 /* CREATING THE DATA STRUCTURES */
2302 /******************************************************************************/
2304 #ifdef ENABLE_VERIFIER
2305 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2306 methodinfo *refmethod,
2307 unresolved_subtype_set *stset,
2309 utf *declaredclassname)
2317 #ifdef RESOLVE_VERBOSE
2318 printf("unresolved_subtype_set_from_typeinfo\n");
2319 #ifdef TYPEINFO_DEBUG
2320 typeinfo_print(stdout,tinfo,4);
2322 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2326 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2327 exceptions_throw_verifyerror(refmethod,
2328 "Invalid use of returnAddress");
2332 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2333 exceptions_throw_verifyerror(refmethod,
2334 "Invalid use of uninitialized object");
2338 /* the nulltype is always assignable */
2339 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2342 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2343 if (declaredclassname == utf_java_lang_Object
2344 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2349 if (tinfo->merged) {
2350 count = tinfo->merged->count;
2351 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2352 for (i=0; i<count; ++i) {
2353 classref_or_classinfo c = tinfo->merged->list[i];
2354 if (tinfo->dimension > 0) {
2355 /* a merge of array types */
2356 /* the merged list contains the possible _element_ types, */
2357 /* so we have to create array types with these elements. */
2358 if (IS_CLASSREF(c)) {
2359 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2362 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2365 stset->subtyperefs[i] = c;
2367 stset->subtyperefs[count].any = NULL; /* terminate */
2370 if ((IS_CLASSREF(tinfo->typeclass)
2371 ? tinfo->typeclass.ref->name
2372 : tinfo->typeclass.cls->name) == declaredclassname)
2374 /* the class names are the same */
2375 /* equality is guaranteed by the loading constraints */
2379 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2380 stset->subtyperefs[0] = tinfo->typeclass;
2381 stset->subtyperefs[1].any = NULL; /* terminate */
2388 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2391 #endif /* ENABLE_VERIFIER */
2393 /* create_unresolved_class *****************************************************
2395 Create an unresolved_class struct for the given class reference
2398 refmethod........the method triggering the resolution (if any)
2399 classref.........the class reference
2400 valuetype........value type to check against the resolved class
2401 may be NULL, if no typeinfo is available
2404 a pointer to a new unresolved_class struct, or
2405 NULL if an exception has been thrown
2407 *******************************************************************************/
2409 #ifdef ENABLE_VERIFIER
2410 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2411 constant_classref *classref,
2412 typeinfo_t *valuetype)
2414 unresolved_class *ref;
2416 #ifdef RESOLVE_VERBOSE
2417 printf("create_unresolved_class\n");
2418 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2420 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2421 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2423 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2426 ref = NEW(unresolved_class);
2427 ref->classref = classref;
2428 ref->referermethod = refmethod;
2431 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2432 &(ref->subtypeconstraints),valuetype,classref->name))
2436 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2441 #endif /* ENABLE_VERIFIER */
2443 /* resolve_create_unresolved_field *********************************************
2445 Create an unresolved_field struct for the given field access instruction
2448 referer..........the class containing the reference
2449 refmethod........the method triggering the resolution (if any)
2450 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2453 a pointer to a new unresolved_field struct, or
2454 NULL if an exception has been thrown
2456 *******************************************************************************/
2458 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2459 methodinfo *refmethod,
2462 unresolved_field *ref;
2463 constant_FMIref *fieldref = NULL;
2465 #ifdef RESOLVE_VERBOSE
2466 printf("create_unresolved_field\n");
2467 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2468 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2469 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2472 ref = NEW(unresolved_field);
2474 ref->referermethod = refmethod;
2475 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2477 switch (iptr->opc) {
2479 ref->flags |= RESOLVE_PUTFIELD;
2482 case ICMD_PUTFIELDCONST:
2483 ref->flags |= RESOLVE_PUTFIELD;
2486 case ICMD_PUTSTATIC:
2487 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2490 case ICMD_PUTSTATICCONST:
2491 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2497 case ICMD_GETSTATIC:
2498 ref->flags |= RESOLVE_STATIC;
2501 #if !defined(NDEBUG)
2507 fieldref = iptr->sx.s23.s3.fmiref;
2511 #ifdef RESOLVE_VERBOSE
2512 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2513 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2514 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2515 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2519 ref->fieldref = fieldref;
2524 /* resolve_constrain_unresolved_field ******************************************
2526 Record subtype constraints for a field access.
2529 ref..............the unresolved_field structure of the access
2530 referer..........the class containing the reference
2531 refmethod........the method triggering the resolution (if any)
2532 instanceti.......instance typeinfo, if available
2533 valueti..........value typeinfo, if available
2536 true.............everything ok
2537 false............an exception has been thrown
2539 *******************************************************************************/
2541 #if defined(ENABLE_VERIFIER)
2542 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2544 methodinfo *refmethod,
2545 typeinfo_t *instanceti,
2546 typeinfo_t *valueti)
2548 constant_FMIref *fieldref;
2555 fieldref = ref->fieldref;
2558 #ifdef RESOLVE_VERBOSE
2559 printf("constrain_unresolved_field\n");
2560 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2561 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2562 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2563 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2564 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2565 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2566 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2570 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2571 fd = fieldref->parseddesc.fd;
2574 /* record subtype constraints for the instance type, if any */
2576 typeinfo_t *insttip;
2578 /* The instanceslot must contain a reference to a non-array type */
2579 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2580 exceptions_throw_verifyerror(refmethod,
2581 "illegal instruction: field access on non-reference");
2584 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2585 exceptions_throw_verifyerror(refmethod,
2586 "illegal instruction: field access on array");
2590 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2591 TYPEINFO_IS_NEWOBJECT(*instanceti))
2593 /* The instruction writes a field in an uninitialized object. */
2594 /* This is only allowed when a field of an uninitialized 'this' object is */
2595 /* written inside an initialization method */
2597 classinfo *initclass;
2598 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2601 exceptions_throw_verifyerror(refmethod,
2602 "accessing field of uninitialized object");
2605 /* XXX check that class of field == refmethod->clazz */
2606 initclass = refmethod->clazz; /* XXX classrefs */
2607 assert(initclass->state & CLASS_LOADED);
2608 assert(initclass->state & CLASS_LINKED);
2610 typeinfo_init_classinfo(&tinfo, initclass);
2614 insttip = instanceti;
2616 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2617 &(ref->instancetypes), insttip,
2618 FIELDREF_CLASSNAME(fieldref)))
2622 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2625 /* record subtype constraints for the value type, if any */
2627 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2629 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2630 &(ref->valueconstraints), valueti,
2631 fieldref->parseddesc.fd->classref->name))
2635 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2640 #endif /* ENABLE_VERIFIER */
2642 /* resolve_create_unresolved_method ********************************************
2644 Create an unresolved_method struct for the given method invocation
2647 referer..........the class containing the reference
2648 refmethod........the method triggering the resolution (if any)
2649 iptr.............the INVOKE* instruction
2652 a pointer to a new unresolved_method struct
2654 *******************************************************************************/
2656 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2657 methodinfo *refmethod,
2658 constant_FMIref *methodref,
2662 unresolved_method *ref;
2666 #ifdef RESOLVE_VERBOSE
2667 printf("create_unresolved_method\n");
2668 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2669 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2670 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2671 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2672 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2675 /* allocate params if necessary */
2676 descriptor_params_from_paramtypes(
2677 methodref->parseddesc.md,
2678 (invokestatic) ? ACC_STATIC : ACC_NONE);
2680 /* create the data structure */
2681 ref = NEW(unresolved_method);
2682 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2683 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2684 ref->referermethod = refmethod;
2685 ref->methodref = methodref;
2686 ref->paramconstraints = NULL;
2687 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2693 /* resolve_constrain_unresolved_method_instance ********************************
2695 Record subtype constraints for the instance argument of a method call.
2698 ref..............the unresolved_method structure of the call
2699 referer..........the class containing the reference
2700 refmethod........the method triggering the resolution (if any)
2701 iptr.............the INVOKE* instruction
2704 true.............everything ok
2705 false............an exception has been thrown
2707 *******************************************************************************/
2709 #if defined(ENABLE_VERIFIER)
2710 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2711 methodinfo *refmethod,
2712 typeinfo_t *instanceti,
2715 constant_FMIref *methodref;
2716 constant_classref *instanceref;
2721 methodref = ref->methodref;
2724 /* XXX clean this up */
2725 instanceref = IS_FMIREF_RESOLVED(methodref)
2726 ? class_get_self_classref(methodref->p.method->clazz)
2727 : methodref->p.classref;
2729 #ifdef RESOLVE_VERBOSE
2730 printf("resolve_constrain_unresolved_method_instance\n");
2731 printf(" rmethod: "); method_println(refmethod);
2732 printf(" mref : "); method_methodref_println(methodref);
2735 /* record subtype constraints for the instance type, if any */
2737 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2738 { /* XXX clean up */
2739 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2740 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2741 : CLASSREF_OR_CLASSINFO(refmethod->clazz);
2743 if (!typeinfo_init_class(tip, initclass))
2750 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2751 &(ref->instancetypes),tip,instanceref->name))
2756 #endif /* defined(ENABLE_VERIFIER) */
2759 /* resolve_constrain_unresolved_method_params *********************************
2761 Record subtype constraints for the non-instance arguments of a method call.
2764 jd...............current jitdata (for looking up variables)
2765 ref..............the unresolved_method structure of the call
2766 refmethod........the method triggering the resolution (if any)
2767 iptr.............the INVOKE* instruction
2770 true.............everything ok
2771 false............an exception has been thrown
2773 *******************************************************************************/
2775 #if defined(ENABLE_VERIFIER)
2776 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2777 unresolved_method *ref,
2778 methodinfo *refmethod,
2781 constant_FMIref *methodref;
2789 methodref = ref->methodref;
2791 md = methodref->parseddesc.md;
2793 assert(md->params != NULL);
2795 #ifdef RESOLVE_VERBOSE
2796 printf("resolve_constrain_unresolved_method_params\n");
2797 printf(" rmethod: "); method_println(refmethod);
2798 printf(" mref : "); method_methodref_println(methodref);
2801 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2803 /* record subtype constraints for the parameter types, if any */
2805 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2806 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2807 type = md->paramtypes[i+instancecount].type;
2810 assert(type == param->type);
2812 if (type == TYPE_ADR) {
2813 if (!ref->paramconstraints) {
2814 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2815 for (j=md->paramcount-1-instancecount; j>i; --j)
2816 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2818 assert(ref->paramconstraints);
2819 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2820 ref->paramconstraints + i,&(param->typeinfo),
2821 md->paramtypes[i+instancecount].classref->name))
2825 if (ref->paramconstraints)
2826 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2832 #endif /* ENABLE_VERIFIER */
2835 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2837 Record subtype constraints for the non-instance arguments of a method call.
2840 ref..............the unresolved_method structure of the call
2841 refmethod........the method triggering the resolution (if any)
2842 stack............TOS before the INVOKE instruction
2845 true.............everything ok
2846 false............an exception has been thrown
2848 *******************************************************************************/
2850 #if defined(ENABLE_VERIFIER)
2851 bool resolve_constrain_unresolved_method_params_stackbased(
2852 unresolved_method *ref,
2853 methodinfo *refmethod,
2854 typedescriptor_t *stack)
2856 constant_FMIref *methodref;
2857 typedescriptor_t *param;
2864 methodref = ref->methodref;
2866 md = methodref->parseddesc.md;
2868 assert(md->params != NULL);
2870 #ifdef RESOLVE_VERBOSE
2871 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2872 printf(" rmethod: "); method_println(refmethod);
2873 printf(" mref : "); method_methodref_println(methodref);
2876 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2878 /* record subtype constraints for the parameter types, if any */
2880 param = stack - (md->paramslots - 1 - instancecount);
2882 for (i = instancecount; i < md->paramcount; ++i) {
2883 type = md->paramtypes[i].type;
2885 assert(type == param->type);
2887 if (type == TYPE_ADR) {
2888 if (!ref->paramconstraints) {
2889 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2890 for (j = 0; j < i - instancecount; ++j)
2891 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2893 assert(ref->paramconstraints);
2894 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2895 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2896 md->paramtypes[i].classref->name))
2900 if (ref->paramconstraints)
2901 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2904 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2909 #endif /* ENABLE_VERIFIER */
2912 /******************************************************************************/
2913 /* FREEING MEMORY */
2914 /******************************************************************************/
2916 #ifdef ENABLE_VERIFIER
2917 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2920 classref_or_classinfo *p = list;
2922 /* this is silly. we *only* need to count the elements for MFREE */
2925 MFREE(list,classref_or_classinfo,(p - list));
2928 #endif /* ENABLE_VERIFIER */
2930 /* unresolved_class_free *******************************************************
2932 Free the memory used by an unresolved_class
2935 ref..............the unresolved_class
2937 *******************************************************************************/
2939 void unresolved_class_free(unresolved_class *ref)
2943 #ifdef ENABLE_VERIFIER
2944 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2946 FREE(ref,unresolved_class);
2949 /* unresolved_field_free *******************************************************
2951 Free the memory used by an unresolved_field
2954 ref..............the unresolved_field
2956 *******************************************************************************/
2958 void unresolved_field_free(unresolved_field *ref)
2962 #ifdef ENABLE_VERIFIER
2963 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2964 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2966 FREE(ref,unresolved_field);
2969 /* unresolved_method_free ******************************************************
2971 Free the memory used by an unresolved_method
2974 ref..............the unresolved_method
2976 *******************************************************************************/
2978 void unresolved_method_free(unresolved_method *ref)
2982 #ifdef ENABLE_VERIFIER
2983 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2984 if (ref->paramconstraints) {
2986 int count = ref->methodref->parseddesc.md->paramcount;
2988 for (i=0; i<count; ++i)
2989 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2990 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2993 FREE(ref,unresolved_method);
2996 /******************************************************************************/
2998 /******************************************************************************/
3000 #if !defined(NDEBUG)
3002 /* unresolved_subtype_set_debug_dump *******************************************
3004 Print debug info for unresolved_subtype_set to stream
3007 stset............the unresolved_subtype_set
3008 file.............the stream
3010 *******************************************************************************/
3012 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
3014 classref_or_classinfo *p;
3016 if (SUBTYPESET_IS_EMPTY(*stset)) {
3017 fprintf(file," (empty)\n");
3020 p = stset->subtyperefs;
3021 for (;p->any; ++p) {
3022 if (IS_CLASSREF(*p)) {
3023 fprintf(file," ref: ");
3024 utf_fprint_printable_ascii(file,p->ref->name);
3027 fprintf(file," cls: ");
3028 utf_fprint_printable_ascii(file,p->cls->name);
3035 /* unresolved_class_debug_dump *************************************************
3037 Print debug info for unresolved_class to stream
3040 ref..............the unresolved_class
3041 file.............the stream
3043 *******************************************************************************/
3045 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3047 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3049 fprintf(file," referer : ");
3050 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3051 fprintf(file," refmethod : ");
3052 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3053 fprintf(file," refmethodd: ");
3054 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3055 fprintf(file," classname : ");
3056 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3057 fprintf(file," subtypeconstraints:\n");
3058 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3062 /* unresolved_field_debug_dump *************************************************
3064 Print debug info for unresolved_field to stream
3067 ref..............the unresolved_field
3068 file.............the stream
3070 *******************************************************************************/
3072 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3074 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3076 fprintf(file," referer : ");
3077 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3078 fprintf(file," refmethod : ");
3079 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3080 fprintf(file," refmethodd: ");
3081 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3082 fprintf(file," classname : ");
3083 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3084 fprintf(file," name : ");
3085 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3086 fprintf(file," descriptor: ");
3087 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3088 fprintf(file," parseddesc: ");
3089 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3090 fprintf(file," flags : %04x\n",ref->flags);
3091 fprintf(file," instancetypes:\n");
3092 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3093 fprintf(file," valueconstraints:\n");
3094 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3098 /* unresolved_method_debug_dump ************************************************
3100 Print debug info for unresolved_method to stream
3103 ref..............the unresolved_method
3104 file.............the stream
3106 *******************************************************************************/
3108 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3112 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3114 fprintf(file," referer : ");
3115 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3116 fprintf(file," refmethod : ");
3117 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3118 fprintf(file," refmethodd: ");
3119 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3120 fprintf(file," classname : ");
3121 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3122 fprintf(file," name : ");
3123 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3124 fprintf(file," descriptor: ");
3125 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3126 fprintf(file," parseddesc: ");
3127 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3128 fprintf(file," flags : %04x\n",ref->flags);
3129 fprintf(file," instancetypes:\n");
3130 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3131 fprintf(file," paramconstraints:\n");
3132 if (ref->paramconstraints) {
3133 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3134 fprintf(file," param %d:\n",i);
3135 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3139 fprintf(file," (empty)\n");
3143 #endif /* !defined(NDEBUG) */
3147 * These are local overrides for various environment variables in Emacs.
3148 * Please do not remove this and leave it at the end of the file, where
3149 * Emacs will automagically detect them.
3150 * ---------------------------------------------------------------------
3153 * indent-tabs-mode: t
3157 * vim:noexpandtab:sw=4:ts=4: