1 /* src/vm/resolve.cpp - resolving classes/interfaces/fields/methods
3 Copyright (C) 1996-2005, 2006, 2007, 2008
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 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2072 return resolveFailed;
2074 /* cache the result of the resolution */
2076 methodref->p.method = mi;
2080 return resolveSucceeded;
2083 /* resolve_method **************************************************************
2085 Resolve an unresolved method reference
2088 ref..............struct containing the reference
2089 mode.............mode of resolution:
2090 resolveLazy...only resolve if it does not
2091 require loading classes
2092 resolveEager..load classes if necessary
2095 *result..........set to the result of resolution, or to NULL if
2096 the reference has not been resolved
2097 In the case of an exception, *result is
2098 guaranteed to be set to NULL.
2101 true.............everything ok
2102 (*result may still be NULL for resolveLazy)
2103 false............an exception has been thrown
2105 *******************************************************************************/
2107 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2110 classinfo *container;
2111 classinfo *declarer;
2113 typedesc *paramtypes;
2116 resolve_result_t checkresult;
2120 assert(mode == resolveLazy || mode == resolveEager);
2122 #ifdef RESOLVE_VERBOSE
2123 unresolved_method_debug_dump(ref,stdout);
2128 /* the class containing the reference */
2130 referer = ref->referermethod->clazz;
2133 /* check if the method itself is already resolved */
2135 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2136 mi = ref->methodref->p.method;
2137 container = mi->clazz;
2138 goto resolved_the_method;
2141 /* first we must resolve the class containing the method */
2143 if (!resolve_class_from_name(referer,ref->referermethod,
2144 ref->methodref->p.classref->name,mode,true,true,&container))
2146 /* the class reference could not be resolved */
2147 return false; /* exception */
2150 return true; /* be lazy */
2153 assert(container->state & CLASS_LINKED);
2155 /* now we must find the declaration of the method in `container`
2156 * or one of its superclasses */
2158 if (container->flags & ACC_INTERFACE) {
2159 mi = class_resolveinterfacemethod(container,
2160 ref->methodref->name,
2161 ref->methodref->descriptor,
2165 mi = class_resolveclassmethod(container,
2166 ref->methodref->name,
2167 ref->methodref->descriptor,
2172 if (mode == resolveLazy) {
2173 /* The method does not exist. But since we were called lazily, */
2174 /* this error must not be reported now. (It will be reported */
2175 /* if eager resolving of this method is ever tried.) */
2177 exceptions_clear_exception();
2178 return true; /* be lazy */
2181 return false; /* exception */ /* XXX set exceptionptr? */
2184 /* { the method reference has been resolved } */
2186 if (ref->flags & RESOLVE_SPECIAL) {
2187 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2189 return false; /* exception */
2192 /* have the method params already been parsed? no, do it. */
2194 if (!mi->parseddesc->params)
2195 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2198 /* cache the resolution */
2200 ref->methodref->p.method = mi;
2202 resolved_the_method:
2204 #ifdef ENABLE_VERIFIER
2207 checkresult = resolve_method_verifier_checks(
2211 (ref->flags & RESOLVE_STATIC));
2213 if (checkresult != resolveSucceeded)
2214 return (bool) checkresult;
2216 /* impose loading constraints on params and return type */
2218 if (!resolve_method_loading_constraints(referer, mi))
2221 declarer = mi->clazz;
2223 assert(referer->state & CLASS_LINKED);
2225 /* for non-static methods we have to check the constraints on the */
2228 if (!(ref->flags & RESOLVE_STATIC)) {
2229 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2230 &(ref->instancetypes),
2231 CLASSREF_OR_CLASSINFO(container),
2233 resolveLinkageError);
2234 if (checkresult != resolveSucceeded)
2235 return (bool) checkresult;
2242 /* check subtype constraints for TYPE_ADR parameters */
2244 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2245 paramtypes = mi->parseddesc->paramtypes;
2247 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2248 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2249 if (ref->paramconstraints) {
2250 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2251 ref->paramconstraints + i,
2252 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2254 resolveLinkageError);
2255 if (checkresult != resolveSucceeded)
2256 return (bool) checkresult;
2261 /* check protected access */
2263 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2265 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2266 &(ref->instancetypes),
2267 CLASSREF_OR_CLASSINFO(referer),
2269 resolveIllegalAccessError);
2270 if (checkresult != resolveSucceeded)
2271 return (bool) checkresult;
2274 #endif /* ENABLE_VERIFIER */
2281 /* resolve_method_eager ********************************************************
2283 Resolve an unresolved method reference eagerly.
2286 ref..............struct containing the reference
2289 methodinfo * to the method, or
2290 NULL if an exception has been thrown
2292 *******************************************************************************/
2294 methodinfo * resolve_method_eager(unresolved_method *ref)
2298 if (!resolve_method(ref,resolveEager,&mi))
2304 /******************************************************************************/
2305 /* CREATING THE DATA STRUCTURES */
2306 /******************************************************************************/
2308 #ifdef ENABLE_VERIFIER
2309 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2310 methodinfo *refmethod,
2311 unresolved_subtype_set *stset,
2313 utf *declaredclassname)
2321 #ifdef RESOLVE_VERBOSE
2322 printf("unresolved_subtype_set_from_typeinfo\n");
2323 #ifdef TYPEINFO_DEBUG
2324 typeinfo_print(stdout,tinfo,4);
2326 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2330 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2331 exceptions_throw_verifyerror(refmethod,
2332 "Invalid use of returnAddress");
2336 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2337 exceptions_throw_verifyerror(refmethod,
2338 "Invalid use of uninitialized object");
2342 /* the nulltype is always assignable */
2343 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2346 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2347 if (declaredclassname == utf_java_lang_Object
2348 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2353 if (tinfo->merged) {
2354 count = tinfo->merged->count;
2355 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2356 for (i=0; i<count; ++i) {
2357 classref_or_classinfo c = tinfo->merged->list[i];
2358 if (tinfo->dimension > 0) {
2359 /* a merge of array types */
2360 /* the merged list contains the possible _element_ types, */
2361 /* so we have to create array types with these elements. */
2362 if (IS_CLASSREF(c)) {
2363 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2366 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2369 stset->subtyperefs[i] = c;
2371 stset->subtyperefs[count].any = NULL; /* terminate */
2374 if ((IS_CLASSREF(tinfo->typeclass)
2375 ? tinfo->typeclass.ref->name
2376 : tinfo->typeclass.cls->name) == declaredclassname)
2378 /* the class names are the same */
2379 /* equality is guaranteed by the loading constraints */
2383 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2384 stset->subtyperefs[0] = tinfo->typeclass;
2385 stset->subtyperefs[1].any = NULL; /* terminate */
2392 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2395 #endif /* ENABLE_VERIFIER */
2397 /* create_unresolved_class *****************************************************
2399 Create an unresolved_class struct for the given class reference
2402 refmethod........the method triggering the resolution (if any)
2403 classref.........the class reference
2404 valuetype........value type to check against the resolved class
2405 may be NULL, if no typeinfo is available
2408 a pointer to a new unresolved_class struct, or
2409 NULL if an exception has been thrown
2411 *******************************************************************************/
2413 #ifdef ENABLE_VERIFIER
2414 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2415 constant_classref *classref,
2416 typeinfo_t *valuetype)
2418 unresolved_class *ref;
2420 #ifdef RESOLVE_VERBOSE
2421 printf("create_unresolved_class\n");
2422 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2424 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2425 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2427 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2430 ref = NEW(unresolved_class);
2431 ref->classref = classref;
2432 ref->referermethod = refmethod;
2435 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2436 &(ref->subtypeconstraints),valuetype,classref->name))
2440 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2445 #endif /* ENABLE_VERIFIER */
2447 /* resolve_create_unresolved_field *********************************************
2449 Create an unresolved_field struct for the given field access instruction
2452 referer..........the class containing the reference
2453 refmethod........the method triggering the resolution (if any)
2454 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2457 a pointer to a new unresolved_field struct, or
2458 NULL if an exception has been thrown
2460 *******************************************************************************/
2462 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2463 methodinfo *refmethod,
2466 unresolved_field *ref;
2467 constant_FMIref *fieldref = NULL;
2469 #ifdef RESOLVE_VERBOSE
2470 printf("create_unresolved_field\n");
2471 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2472 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2473 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2476 ref = NEW(unresolved_field);
2478 ref->referermethod = refmethod;
2479 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2481 switch (iptr->opc) {
2483 ref->flags |= RESOLVE_PUTFIELD;
2486 case ICMD_PUTFIELDCONST:
2487 ref->flags |= RESOLVE_PUTFIELD;
2490 case ICMD_PUTSTATIC:
2491 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2494 case ICMD_PUTSTATICCONST:
2495 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2501 case ICMD_GETSTATIC:
2502 ref->flags |= RESOLVE_STATIC;
2505 #if !defined(NDEBUG)
2511 fieldref = iptr->sx.s23.s3.fmiref;
2515 #ifdef RESOLVE_VERBOSE
2516 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2517 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2518 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2519 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2523 ref->fieldref = fieldref;
2528 /* resolve_constrain_unresolved_field ******************************************
2530 Record subtype constraints for a field access.
2533 ref..............the unresolved_field structure of the access
2534 referer..........the class containing the reference
2535 refmethod........the method triggering the resolution (if any)
2536 instanceti.......instance typeinfo, if available
2537 valueti..........value typeinfo, if available
2540 true.............everything ok
2541 false............an exception has been thrown
2543 *******************************************************************************/
2545 #if defined(ENABLE_VERIFIER)
2546 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2548 methodinfo *refmethod,
2549 typeinfo_t *instanceti,
2550 typeinfo_t *valueti)
2552 constant_FMIref *fieldref;
2559 fieldref = ref->fieldref;
2562 #ifdef RESOLVE_VERBOSE
2563 printf("constrain_unresolved_field\n");
2564 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2565 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2566 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2567 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2568 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2569 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2570 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2574 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2575 fd = fieldref->parseddesc.fd;
2578 /* record subtype constraints for the instance type, if any */
2580 typeinfo_t *insttip;
2582 /* The instanceslot must contain a reference to a non-array type */
2583 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2584 exceptions_throw_verifyerror(refmethod,
2585 "illegal instruction: field access on non-reference");
2588 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2589 exceptions_throw_verifyerror(refmethod,
2590 "illegal instruction: field access on array");
2594 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2595 TYPEINFO_IS_NEWOBJECT(*instanceti))
2597 /* The instruction writes a field in an uninitialized object. */
2598 /* This is only allowed when a field of an uninitialized 'this' object is */
2599 /* written inside an initialization method */
2601 classinfo *initclass;
2602 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2605 exceptions_throw_verifyerror(refmethod,
2606 "accessing field of uninitialized object");
2609 /* XXX check that class of field == refmethod->clazz */
2610 initclass = refmethod->clazz; /* XXX classrefs */
2611 assert(initclass->state & CLASS_LOADED);
2612 assert(initclass->state & CLASS_LINKED);
2614 typeinfo_init_classinfo(&tinfo, initclass);
2618 insttip = instanceti;
2620 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2621 &(ref->instancetypes), insttip,
2622 FIELDREF_CLASSNAME(fieldref)))
2626 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2629 /* record subtype constraints for the value type, if any */
2631 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2633 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2634 &(ref->valueconstraints), valueti,
2635 fieldref->parseddesc.fd->classref->name))
2639 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2644 #endif /* ENABLE_VERIFIER */
2646 /* resolve_create_unresolved_method ********************************************
2648 Create an unresolved_method struct for the given method invocation
2651 referer..........the class containing the reference
2652 refmethod........the method triggering the resolution (if any)
2653 iptr.............the INVOKE* instruction
2656 a pointer to a new unresolved_method struct, or
2657 NULL if an exception has been thrown
2659 *******************************************************************************/
2661 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2662 methodinfo *refmethod,
2663 constant_FMIref *methodref,
2667 unresolved_method *ref;
2671 #ifdef RESOLVE_VERBOSE
2672 printf("create_unresolved_method\n");
2673 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2674 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2675 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2676 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2677 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2680 /* allocate params if necessary */
2681 if (!methodref->parseddesc.md->params)
2682 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2683 (invokestatic) ? ACC_STATIC : ACC_NONE))
2686 /* create the data structure */
2687 ref = NEW(unresolved_method);
2688 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2689 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2690 ref->referermethod = refmethod;
2691 ref->methodref = methodref;
2692 ref->paramconstraints = NULL;
2693 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2699 /* resolve_constrain_unresolved_method_instance ********************************
2701 Record subtype constraints for the instance argument of a method call.
2704 ref..............the unresolved_method structure of the call
2705 referer..........the class containing the reference
2706 refmethod........the method triggering the resolution (if any)
2707 iptr.............the INVOKE* instruction
2710 true.............everything ok
2711 false............an exception has been thrown
2713 *******************************************************************************/
2715 #if defined(ENABLE_VERIFIER)
2716 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2717 methodinfo *refmethod,
2718 typeinfo_t *instanceti,
2721 constant_FMIref *methodref;
2722 constant_classref *instanceref;
2727 methodref = ref->methodref;
2730 /* XXX clean this up */
2731 instanceref = IS_FMIREF_RESOLVED(methodref)
2732 ? class_get_self_classref(methodref->p.method->clazz)
2733 : methodref->p.classref;
2735 #ifdef RESOLVE_VERBOSE
2736 printf("resolve_constrain_unresolved_method_instance\n");
2737 printf(" rmethod: "); method_println(refmethod);
2738 printf(" mref : "); method_methodref_println(methodref);
2741 /* record subtype constraints for the instance type, if any */
2743 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2744 { /* XXX clean up */
2745 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2746 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2747 : CLASSREF_OR_CLASSINFO(refmethod->clazz);
2749 if (!typeinfo_init_class(tip, initclass))
2756 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2757 &(ref->instancetypes),tip,instanceref->name))
2762 #endif /* defined(ENABLE_VERIFIER) */
2765 /* resolve_constrain_unresolved_method_params *********************************
2767 Record subtype constraints for the non-instance arguments of a method call.
2770 jd...............current jitdata (for looking up variables)
2771 ref..............the unresolved_method structure of the call
2772 refmethod........the method triggering the resolution (if any)
2773 iptr.............the INVOKE* instruction
2776 true.............everything ok
2777 false............an exception has been thrown
2779 *******************************************************************************/
2781 #if defined(ENABLE_VERIFIER)
2782 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2783 unresolved_method *ref,
2784 methodinfo *refmethod,
2787 constant_FMIref *methodref;
2795 methodref = ref->methodref;
2797 md = methodref->parseddesc.md;
2799 assert(md->params != NULL);
2801 #ifdef RESOLVE_VERBOSE
2802 printf("resolve_constrain_unresolved_method_params\n");
2803 printf(" rmethod: "); method_println(refmethod);
2804 printf(" mref : "); method_methodref_println(methodref);
2807 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2809 /* record subtype constraints for the parameter types, if any */
2811 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2812 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2813 type = md->paramtypes[i+instancecount].type;
2816 assert(type == param->type);
2818 if (type == TYPE_ADR) {
2819 if (!ref->paramconstraints) {
2820 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2821 for (j=md->paramcount-1-instancecount; j>i; --j)
2822 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2824 assert(ref->paramconstraints);
2825 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2826 ref->paramconstraints + i,&(param->typeinfo),
2827 md->paramtypes[i+instancecount].classref->name))
2831 if (ref->paramconstraints)
2832 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2838 #endif /* ENABLE_VERIFIER */
2841 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2843 Record subtype constraints for the non-instance arguments of a method call.
2846 ref..............the unresolved_method structure of the call
2847 refmethod........the method triggering the resolution (if any)
2848 stack............TOS before the INVOKE instruction
2851 true.............everything ok
2852 false............an exception has been thrown
2854 *******************************************************************************/
2856 #if defined(ENABLE_VERIFIER)
2857 bool resolve_constrain_unresolved_method_params_stackbased(
2858 unresolved_method *ref,
2859 methodinfo *refmethod,
2860 typedescriptor_t *stack)
2862 constant_FMIref *methodref;
2863 typedescriptor_t *param;
2870 methodref = ref->methodref;
2872 md = methodref->parseddesc.md;
2874 assert(md->params != NULL);
2876 #ifdef RESOLVE_VERBOSE
2877 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2878 printf(" rmethod: "); method_println(refmethod);
2879 printf(" mref : "); method_methodref_println(methodref);
2882 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2884 /* record subtype constraints for the parameter types, if any */
2886 param = stack - (md->paramslots - 1 - instancecount);
2888 for (i = instancecount; i < md->paramcount; ++i) {
2889 type = md->paramtypes[i].type;
2891 assert(type == param->type);
2893 if (type == TYPE_ADR) {
2894 if (!ref->paramconstraints) {
2895 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2896 for (j = 0; j < i - instancecount; ++j)
2897 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2899 assert(ref->paramconstraints);
2900 if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2901 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2902 md->paramtypes[i].classref->name))
2906 if (ref->paramconstraints)
2907 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2910 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2915 #endif /* ENABLE_VERIFIER */
2918 /******************************************************************************/
2919 /* FREEING MEMORY */
2920 /******************************************************************************/
2922 #ifdef ENABLE_VERIFIER
2923 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2926 classref_or_classinfo *p = list;
2928 /* this is silly. we *only* need to count the elements for MFREE */
2931 MFREE(list,classref_or_classinfo,(p - list));
2934 #endif /* ENABLE_VERIFIER */
2936 /* unresolved_class_free *******************************************************
2938 Free the memory used by an unresolved_class
2941 ref..............the unresolved_class
2943 *******************************************************************************/
2945 void unresolved_class_free(unresolved_class *ref)
2949 #ifdef ENABLE_VERIFIER
2950 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2952 FREE(ref,unresolved_class);
2955 /* unresolved_field_free *******************************************************
2957 Free the memory used by an unresolved_field
2960 ref..............the unresolved_field
2962 *******************************************************************************/
2964 void unresolved_field_free(unresolved_field *ref)
2968 #ifdef ENABLE_VERIFIER
2969 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2970 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2972 FREE(ref,unresolved_field);
2975 /* unresolved_method_free ******************************************************
2977 Free the memory used by an unresolved_method
2980 ref..............the unresolved_method
2982 *******************************************************************************/
2984 void unresolved_method_free(unresolved_method *ref)
2988 #ifdef ENABLE_VERIFIER
2989 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2990 if (ref->paramconstraints) {
2992 int count = ref->methodref->parseddesc.md->paramcount;
2994 for (i=0; i<count; ++i)
2995 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2996 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2999 FREE(ref,unresolved_method);
3002 /******************************************************************************/
3004 /******************************************************************************/
3006 #if !defined(NDEBUG)
3008 /* unresolved_subtype_set_debug_dump *******************************************
3010 Print debug info for unresolved_subtype_set to stream
3013 stset............the unresolved_subtype_set
3014 file.............the stream
3016 *******************************************************************************/
3018 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
3020 classref_or_classinfo *p;
3022 if (SUBTYPESET_IS_EMPTY(*stset)) {
3023 fprintf(file," (empty)\n");
3026 p = stset->subtyperefs;
3027 for (;p->any; ++p) {
3028 if (IS_CLASSREF(*p)) {
3029 fprintf(file," ref: ");
3030 utf_fprint_printable_ascii(file,p->ref->name);
3033 fprintf(file," cls: ");
3034 utf_fprint_printable_ascii(file,p->cls->name);
3041 /* unresolved_class_debug_dump *************************************************
3043 Print debug info for unresolved_class to stream
3046 ref..............the unresolved_class
3047 file.............the stream
3049 *******************************************************************************/
3051 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3053 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3055 fprintf(file," referer : ");
3056 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3057 fprintf(file," refmethod : ");
3058 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3059 fprintf(file," refmethodd: ");
3060 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3061 fprintf(file," classname : ");
3062 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3063 fprintf(file," subtypeconstraints:\n");
3064 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3068 /* unresolved_field_debug_dump *************************************************
3070 Print debug info for unresolved_field to stream
3073 ref..............the unresolved_field
3074 file.............the stream
3076 *******************************************************************************/
3078 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3080 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3082 fprintf(file," referer : ");
3083 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3084 fprintf(file," refmethod : ");
3085 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3086 fprintf(file," refmethodd: ");
3087 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3088 fprintf(file," classname : ");
3089 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3090 fprintf(file," name : ");
3091 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3092 fprintf(file," descriptor: ");
3093 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3094 fprintf(file," parseddesc: ");
3095 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3096 fprintf(file," flags : %04x\n",ref->flags);
3097 fprintf(file," instancetypes:\n");
3098 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3099 fprintf(file," valueconstraints:\n");
3100 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3104 /* unresolved_method_debug_dump ************************************************
3106 Print debug info for unresolved_method to stream
3109 ref..............the unresolved_method
3110 file.............the stream
3112 *******************************************************************************/
3114 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3118 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3120 fprintf(file," referer : ");
3121 utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3122 fprintf(file," refmethod : ");
3123 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3124 fprintf(file," refmethodd: ");
3125 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3126 fprintf(file," classname : ");
3127 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3128 fprintf(file," name : ");
3129 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3130 fprintf(file," descriptor: ");
3131 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3132 fprintf(file," parseddesc: ");
3133 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3134 fprintf(file," flags : %04x\n",ref->flags);
3135 fprintf(file," instancetypes:\n");
3136 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3137 fprintf(file," paramconstraints:\n");
3138 if (ref->paramconstraints) {
3139 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3140 fprintf(file," param %d:\n",i);
3141 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3145 fprintf(file," (empty)\n");
3149 #endif /* !defined(NDEBUG) */
3153 * These are local overrides for various environment variables in Emacs.
3154 * Please do not remove this and leave it at the end of the file, where
3155 * Emacs will automagically detect them.
3156 * ---------------------------------------------------------------------
3159 * indent-tabs-mode: t
3163 * vim:noexpandtab:sw=4:ts=4: