1 /* src/vm/resolve.c - resolving classes/interfaces/fields/methods
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Edwin Steiner
29 Changes: Christan Thalinger
31 $Id: resolve.c 5737 2006-10-11 19:40:22Z edwin $
40 #include "mm/memory.h"
41 #include "vm/resolve.h"
42 #include "vm/access.h"
43 #include "vm/classcache.h"
44 #include "vm/descriptor.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/linker.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/stringlocal.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/verify/typeinfo.h"
55 /******************************************************************************/
57 /******************************************************************************/
59 /*#define RESOLVE_VERBOSE*/
61 /******************************************************************************/
62 /* CLASS RESOLUTION */
63 /******************************************************************************/
65 /* resolve_class_from_name *****************************************************
67 Resolve a symbolic class reference
70 referer..........the class containing the reference
71 refmethod........the method from which resolution was triggered
72 (may be NULL if not applicable)
73 classname........class name to resolve
74 mode.............mode of resolution:
75 resolveLazy...only resolve if it does not
76 require loading classes
77 resolveEager..load classes if necessary
78 checkaccess......if true, access rights to the class are checked
79 link.............if true, guarantee that the returned class, if any,
83 *result..........set to result of resolution, or to NULL if
84 the reference has not been resolved
85 In the case of an exception, *result is
86 guaranteed to be set to NULL.
89 true.............everything ok
90 (*result may still be NULL for resolveLazy)
91 false............an exception has been thrown
94 The returned class is *not* guaranteed to be linked!
95 (It is guaranteed to be loaded, though.)
97 *******************************************************************************/
99 bool resolve_class_from_name(classinfo *referer,
100 methodinfo *refmethod,
107 classinfo *cls = NULL;
114 assert(mode == resolveLazy || mode == resolveEager);
118 #ifdef RESOLVE_VERBOSE
119 printf("resolve_class_from_name(");
120 utf_fprint_printable_ascii(stdout,referer->name);
121 printf(",%p,",(void*)referer->classloader);
122 utf_fprint_printable_ascii(stdout,classname);
123 printf(",%d,%d)\n",(int)checkaccess,(int)link);
126 /* lookup if this class has already been loaded */
128 cls = classcache_lookup(referer->classloader, classname);
130 #ifdef RESOLVE_VERBOSE
131 printf(" lookup result: %p\n",(void*)cls);
135 /* resolve array types */
137 if (classname->text[0] == '[') {
138 utf_ptr = classname->text + 1;
139 len = classname->blength - 1;
141 /* classname is an array type name */
149 /* the component type is a reference type */
150 /* resolve the component type */
151 if (!resolve_class_from_name(referer,refmethod,
152 utf_new(utf_ptr,len),
153 mode,checkaccess,link,&cls))
154 return false; /* exception */
156 assert(mode == resolveLazy);
157 return true; /* be lazy */
159 /* create the array class */
160 cls = class_array_of(cls,false);
162 return false; /* exception */
166 /* the class has not been loaded, yet */
167 if (mode == resolveLazy)
168 return true; /* be lazy */
171 #ifdef RESOLVE_VERBOSE
172 printf(" loading...\n");
177 if (!(cls = load_class_from_classloader(classname,
178 referer->classloader)))
179 return false; /* exception */
183 /* the class is now loaded */
185 assert(cls->state & CLASS_LOADED);
187 #ifdef RESOLVE_VERBOSE
188 printf(" checking access rights...\n");
191 /* check access rights of referer to refered class */
192 if (checkaccess && !access_is_accessible_class(referer,cls)) {
196 msglen = utf_bytes(cls->name) + utf_bytes(referer->name) + 100;
197 message = MNEW(char, msglen);
198 strcpy(message, "class is not accessible (");
199 utf_cat_classname(message, cls->name);
200 strcat(message, " from ");
201 utf_cat_classname(message, referer->name);
202 strcat(message, ")");
203 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
204 MFREE(message,char,msglen);
205 return false; /* exception */
208 /* link the class if necessary */
210 if (!(cls->state & CLASS_LINKED))
211 if (!link_class(cls))
212 return false; /* exception */
214 assert(cls->state & CLASS_LINKED);
217 /* resolution succeeds */
218 #ifdef RESOLVE_VERBOSE
219 printf(" success.\n");
225 /* resolve_classref ************************************************************
227 Resolve a symbolic class reference
230 refmethod........the method from which resolution was triggered
231 (may be NULL if not applicable)
232 ref..............class reference
233 mode.............mode of resolution:
234 resolveLazy...only resolve if it does not
235 require loading classes
236 resolveEager..load classes if necessary
237 checkaccess......if true, access rights to the class are checked
238 link.............if true, guarantee that the returned class, if any,
242 *result..........set to result of resolution, or to NULL if
243 the reference has not been resolved
244 In the case of an exception, *result is
245 guaranteed to be set to NULL.
248 true.............everything ok
249 (*result may still be NULL for resolveLazy)
250 false............an exception has been thrown
252 *******************************************************************************/
254 bool resolve_classref(methodinfo *refmethod,
255 constant_classref *ref,
261 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
264 /* resolve_classref_or_classinfo ***********************************************
266 Resolve a symbolic class reference if necessary
269 refmethod........the method from which resolution was triggered
270 (may be NULL if not applicable)
271 cls..............class reference or classinfo
272 mode.............mode of resolution:
273 resolveLazy...only resolve if it does not
274 require loading classes
275 resolveEager..load classes if necessary
276 checkaccess......if true, access rights to the class are checked
277 link.............if true, guarantee that the returned class, if any,
281 *result..........set to result of resolution, or to NULL if
282 the reference has not been resolved
283 In the case of an exception, *result is
284 guaranteed to be set to NULL.
287 true.............everything ok
288 (*result may still be NULL for resolveLazy)
289 false............an exception has been thrown
291 *******************************************************************************/
293 bool resolve_classref_or_classinfo(methodinfo *refmethod,
294 classref_or_classinfo cls,
303 assert(mode == resolveEager || mode == resolveLazy);
306 #ifdef RESOLVE_VERBOSE
307 printf("resolve_classref_or_classinfo(");
308 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
309 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
314 if (IS_CLASSREF(cls)) {
315 /* we must resolve this reference */
317 if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
318 mode, checkaccess, link, &c))
319 goto return_exception;
322 /* cls has already been resolved */
324 assert(c->state & CLASS_LOADED);
326 assert(c || (mode == resolveLazy));
329 return true; /* be lazy */
332 assert(c->state & CLASS_LOADED);
335 if (!(c->state & CLASS_LINKED))
337 goto return_exception;
339 assert(c->state & CLASS_LINKED);
352 /* resolve_class_from_typedesc *************************************************
354 Return a classinfo * for the given type descriptor
357 d................type descriptor
358 checkaccess......if true, access rights to the class are checked
359 link.............if true, guarantee that the returned class, if any,
362 *result..........set to result of resolution, or to NULL if
363 the reference has not been resolved
364 In the case of an exception, *result is
365 guaranteed to be set to NULL.
368 true.............everything ok
369 false............an exception has been thrown
372 This function always resolves eagerly.
374 *******************************************************************************/
376 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
385 #ifdef RESOLVE_VERBOSE
386 printf("resolve_class_from_typedesc(");
387 descriptor_debug_print_typedesc(stdout,d);
388 printf(",%i,%i)\n",(int)checkaccess,(int)link);
391 if (d->type == TYPE_ADR) {
392 /* a reference type */
394 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
395 resolveEager,checkaccess,link,&cls))
396 return false; /* exception */
399 /* a primitive type */
400 cls = primitivetype_table[d->decltype].class_primitive;
401 assert(cls->state & CLASS_LOADED);
402 if (!(cls->state & CLASS_LINKED))
403 if (!link_class(cls))
404 return false; /* exception */
407 assert(cls->state & CLASS_LOADED);
408 assert(!link || (cls->state & CLASS_LINKED));
410 #ifdef RESOLVE_VERBOSE
411 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
418 /******************************************************************************/
419 /* SUBTYPE SET CHECKS */
420 /******************************************************************************/
422 /* resolve_subtype_check *******************************************************
424 Resolve the given types lazily and perform a subtype check
427 refmethod........the method triggering the resolution
428 subtype..........checked to be a subtype of supertype
429 supertype........the super type to check agaings
430 mode.............mode of resolution:
431 resolveLazy...only resolve if it does not
432 require loading classes
433 resolveEager..load classes if necessary
434 error............which type of exception to throw if
435 the test fails. May be:
436 resolveLinkageError, or
437 resolveIllegalAccessError
438 IMPORTANT: If error==resolveIllegalAccessError,
439 then array types are not checked.
442 resolveSucceeded.....the check succeeded
443 resolveDeferred......the check could not be performed due to
444 unresolved types. (This can only happen for
445 mode == resolveLazy.)
446 resolveFailed........the check failed, an exception has been thrown.
449 The types are resolved first, so any
450 exception which may occurr during resolution may
451 be thrown by this function.
453 *******************************************************************************/
455 #if defined(ENABLE_VERIFIER)
456 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
457 classref_or_classinfo subtype,
458 classref_or_classinfo supertype,
468 assert(supertype.any);
469 assert(mode == resolveLazy || mode == resolveEager);
470 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
472 /* resolve the subtype */
474 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
475 /* the subclass could not be resolved. therefore we are sure that */
476 /* no instances of this subclass will ever exist -> skip this test */
477 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
478 *exceptionptr = NULL;
479 return resolveSucceeded;
482 return resolveDeferred; /* be lazy */
484 assert(subclass->state & CLASS_LINKED);
486 /* do not check access to protected members of arrays */
488 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
489 return resolveSucceeded;
492 /* perform the subtype check */
494 typeinfo_init_classinfo(&subti,subclass);
496 r = typeinfo_is_assignable_to_class(&subti,supertype);
497 if (r == typecheck_FAIL)
498 return resolveFailed; /* failed, exception is already set */
500 if (r == typecheck_MAYBE) {
501 assert(IS_CLASSREF(supertype));
502 if (mode == resolveEager) {
503 if (!resolve_classref_or_classinfo(refmethod,supertype,
504 resolveEager,false,true,
507 return resolveFailed;
509 assert(supertype.cls);
513 return resolveDeferred; /* be lazy */
517 /* sub class relationship is false */
522 #if defined(RESOLVE_VERBOSE)
523 printf("SUBTYPE CHECK FAILED!\n");
526 msglen = utf_bytes(subclass->name) + utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype)) + 200;
527 message = MNEW(char, msglen);
528 strcpy(message, (error == resolveIllegalAccessError) ?
529 "illegal access to protected member ("
530 : "subtype constraint violated (");
531 utf_cat_classname(message, subclass->name);
532 strcat(message, " is not a subclass of ");
533 utf_cat_classname(message, CLASSREF_OR_CLASSINFO_NAME(supertype));
534 strcat(message, ")");
535 if (error == resolveIllegalAccessError)
536 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
538 *exceptionptr = exceptions_new_linkageerror(message, NULL);
539 MFREE(message, char, msglen);
540 return resolveFailed; /* exception */
545 return resolveSucceeded;
547 #endif /* defined(ENABLE_VERIFIER) */
549 /* resolve_lazy_subtype_checks *************************************************
551 Resolve the types to check lazily and perform subtype checks
554 refmethod........the method triggering the resolution
555 subtinfo.........the typeinfo containing the subtypes
556 supertype........the supertype to test againgst
557 mode.............mode of resolution:
558 resolveLazy...only resolve if it does not
559 require loading classes
560 resolveEager..load classes if necessary
561 error............which type of exception to throw if
562 the test fails. May be:
563 resolveLinkageError, or
564 resolveIllegalAccessError
565 IMPORTANT: If error==resolveIllegalAccessError,
566 then array types in the set are skipped.
569 resolveSucceeded.....the check succeeded
570 resolveDeferred......the check could not be performed due to
572 resolveFailed........the check failed, an exception has been thrown.
575 The references in the set are resolved first, so any
576 exception which may occurr during resolution may
577 be thrown by this function.
579 *******************************************************************************/
581 #if defined(ENABLE_VERIFIER)
582 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
584 classref_or_classinfo supertype,
589 resolve_result_t result;
593 assert(supertype.any);
594 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
596 /* returnAddresses are illegal here */
598 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
599 exceptions_throw_verifyerror(refmethod,
600 "Invalid use of returnAddress");
601 return resolveFailed;
604 /* uninitialized objects are illegal here */
606 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
607 exceptions_throw_verifyerror(refmethod,
608 "Invalid use of uninitialized object");
609 return resolveFailed;
612 /* the nulltype is always assignable */
614 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
615 return resolveSucceeded;
617 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
619 if (supertype.cls == class_java_lang_Object
620 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
621 && refmethod->class->classloader == NULL))
623 return resolveSucceeded;
626 if (subtinfo->merged) {
628 /* for a merged type we have to do a series of checks */
630 count = subtinfo->merged->count;
631 for (i=0; i<count; ++i) {
632 classref_or_classinfo c = subtinfo->merged->list[i];
633 if (subtinfo->dimension > 0) {
634 /* a merge of array types */
635 /* the merged list contains the possible _element_ types, */
636 /* so we have to create array types with these elements. */
637 if (IS_CLASSREF(c)) {
638 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
641 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
645 /* do the subtype check against the type c */
647 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
648 if (result != resolveSucceeded)
654 /* a single type, this is the common case, hopefully */
656 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
657 == CLASSREF_OR_CLASSINFO_NAME(supertype))
659 /* the class names are the same */
660 /* equality is guaranteed by the loading constraints */
661 return resolveSucceeded;
665 /* some other type name, try to perform the check lazily */
667 return resolve_subtype_check(refmethod,
668 subtinfo->typeclass,supertype,
675 return resolveSucceeded;
677 #endif /* defined(ENABLE_VERIFIER) */
679 /* resolve_and_check_subtype_set ***********************************************
681 Resolve the references in the given set and test subtype relationships
684 refmethod........the method triggering the resolution
685 ref..............a set of class/interface references
687 typeref..........the type to test against the set
688 mode.............mode of resolution:
689 resolveLazy...only resolve if it does not
690 require loading classes
691 resolveEager..load classes if necessary
692 error............which type of exception to throw if
693 the test fails. May be:
694 resolveLinkageError, or
695 resolveIllegalAccessError
696 IMPORTANT: If error==resolveIllegalAccessError,
697 then array types in the set are skipped.
700 resolveSucceeded.....the check succeeded
701 resolveDeferred......the check could not be performed due to
702 unresolved types. (This can only happen if
703 mode == resolveLazy.)
704 resolveFailed........the check failed, an exception has been thrown.
707 The references in the set are resolved first, so any
708 exception which may occurr during resolution may
709 be thrown by this function.
711 *******************************************************************************/
713 #if defined(ENABLE_VERIFIER)
714 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
715 unresolved_subtype_set *ref,
716 classref_or_classinfo typeref,
720 classref_or_classinfo *setp;
721 typecheck_result checkresult;
726 assert(mode == resolveLazy || mode == resolveEager);
727 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
729 #if defined(RESOLVE_VERBOSE)
730 printf("resolve_and_check_subtype_set:\n");
731 unresolved_subtype_set_debug_dump(ref, stdout);
732 if (IS_CLASSREF(typeref))
733 class_classref_println(typeref.ref);
735 class_println(typeref.cls);
738 setp = ref->subtyperefs;
740 /* an empty set of tests always succeeds */
741 if (!setp || !setp->any) {
742 return resolveSucceeded;
745 /* first resolve the type if necessary */
746 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
747 return resolveFailed; /* exception */
749 return resolveDeferred; /* be lazy */
751 assert(typeref.cls->state & CLASS_LINKED);
753 /* iterate over the set members */
755 for (; setp->any; ++setp) {
756 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
757 #if defined(RESOLVE_VERBOSE)
758 if (checkresult != resolveSucceeded)
759 printf("SUBTYPE CHECK FAILED!\n");
761 if (checkresult != resolveSucceeded)
766 return resolveSucceeded;
768 #endif /* defined(ENABLE_VERIFIER) */
770 /******************************************************************************/
771 /* CLASS RESOLUTION */
772 /******************************************************************************/
774 /* resolve_class ***************************************************************
776 Resolve an unresolved class reference. The class is also linked.
779 ref..............struct containing the reference
780 mode.............mode of resolution:
781 resolveLazy...only resolve if it does not
782 require loading classes
783 resolveEager..load classes if necessary
784 checkaccess......if true, access rights to the class are checked
787 *result..........set to the result of resolution, or to NULL if
788 the reference has not been resolved
789 In the case of an exception, *result is
790 guaranteed to be set to NULL.
793 true.............everything ok
794 (*result may still be NULL for resolveLazy)
795 false............an exception has been thrown
797 *******************************************************************************/
799 #ifdef ENABLE_VERIFIER
800 bool resolve_class(unresolved_class *ref,
806 resolve_result_t checkresult;
810 assert(mode == resolveLazy || mode == resolveEager);
814 #ifdef RESOLVE_VERBOSE
815 unresolved_class_debug_dump(ref,stdout);
818 /* first we must resolve the class */
819 if (!resolve_classref(ref->referermethod,
820 ref->classref,mode,checkaccess,true,&cls))
822 /* the class reference could not be resolved */
823 return false; /* exception */
826 return true; /* be lazy */
829 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
831 /* now we check the subtype constraints */
833 checkresult = resolve_and_check_subtype_set(ref->referermethod,
834 &(ref->subtypeconstraints),
835 CLASSREF_OR_CLASSINFO(cls),
837 resolveLinkageError);
838 if (checkresult != resolveSucceeded)
839 return (bool) checkresult;
845 #endif /* ENABLE_VERIFIER */
847 /* resolve_classref_eager ******************************************************
849 Resolve an unresolved class reference eagerly. The class is also linked and
850 access rights to the class are checked.
853 ref..............constant_classref to the class
856 classinfo * to the class, or
857 NULL if an exception has been thrown
859 *******************************************************************************/
861 classinfo * resolve_classref_eager(constant_classref *ref)
865 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
871 /* resolve_classref_eager_nonabstract ******************************************
873 Resolve an unresolved class reference eagerly. The class is also linked and
874 access rights to the class are checked. A check is performed that the class
878 ref..............constant_classref to the class
881 classinfo * to the class, or
882 NULL if an exception has been thrown
884 *******************************************************************************/
886 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
890 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
893 /* ensure that the class is not abstract */
895 if (c->flags & ACC_ABSTRACT) {
896 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
903 /* resolve_class_eager *********************************************************
905 Resolve an unresolved class reference eagerly. The class is also linked and
906 access rights to the class are checked.
909 ref..............struct containing the reference
912 classinfo * to the class, or
913 NULL if an exception has been thrown
915 *******************************************************************************/
917 #ifdef ENABLE_VERIFIER
918 classinfo * resolve_class_eager(unresolved_class *ref)
922 if (!resolve_class(ref,resolveEager,true,&c))
927 #endif /* ENABLE_VERIFIER */
929 /******************************************************************************/
930 /* FIELD RESOLUTION */
931 /******************************************************************************/
933 /* resolve_field_verifier_checks *******************************************
935 Do the verifier checks necessary after field has been resolved.
938 refmethod........the method containing the reference
939 fieldref.........the field reference
940 container........the class where the field was found
941 fi...............the fieldinfo of the resolved field
942 instanceti.......instance typeinfo, if available
943 valueti..........value typeinfo, if available
944 isstatic.........true if this is a *STATIC* instruction
945 isput............true if this is a PUT* instruction
948 resolveSucceeded....everything ok
949 resolveDeferred.....tests could not be done, have been deferred
950 resolveFailed.......exception has been thrown
952 *******************************************************************************/
954 #if defined(ENABLE_VERIFIER)
955 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
956 constant_FMIref *fieldref,
957 classinfo *container,
959 typeinfo *instanceti,
966 resolve_result_t result;
967 constant_classref *fieldtyperef;
974 /* get the classinfos and the field type */
976 referer = refmethod->class;
979 declarer = fi->class;
981 assert(referer->state & CLASS_LINKED);
983 fieldtyperef = fieldref->parseddesc.fd->classref;
988 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
991 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
992 /* a static field is accessed via an instance, or vice versa */
994 new_exception_message(string_java_lang_IncompatibleClassChangeError,
995 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
996 : "instance field accessed without instance");
997 return resolveFailed;
1000 /* check access rights */
1002 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1006 msglen = utf_bytes(declarer->name) + utf_bytes(fi->name) + utf_bytes(referer->name) + 100;
1007 message = MNEW(char, msglen);
1008 strcpy(message, "field is not accessible (");
1009 utf_cat_classname(message, declarer->name);
1010 strcat(message, ".");
1011 utf_cat(message, fi->name);
1012 strcat(message, " from ");
1013 utf_cat_classname(message, referer->name);
1014 strcat(message, ")");
1015 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1016 MFREE(message,char,msglen);
1017 return resolveFailed; /* exception */
1020 /* for non-static methods we have to check the constraints on the */
1027 /* The instanceslot must contain a reference to a non-array type */
1029 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1030 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1031 return resolveFailed;
1033 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1034 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1035 return resolveFailed;
1038 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1040 /* The instruction writes a field in an uninitialized object. */
1041 /* This is only allowed when a field of an uninitialized 'this' object is */
1042 /* written inside an initialization method */
1044 classinfo *initclass;
1045 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1048 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1049 return resolveFailed;
1052 /* XXX check that class of field == refmethod->class */
1053 initclass = referer; /* XXX classrefs */
1054 assert(initclass->state & CLASS_LINKED);
1056 typeinfo_init_classinfo(&tinfo, initclass);
1060 insttip = instanceti;
1063 result = resolve_lazy_subtype_checks(refmethod,
1065 CLASSREF_OR_CLASSINFO(container),
1066 resolveLinkageError);
1067 if (result != resolveSucceeded)
1070 /* check protected access */
1072 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1074 result = resolve_lazy_subtype_checks(refmethod,
1076 CLASSREF_OR_CLASSINFO(referer),
1077 resolveIllegalAccessError);
1078 if (result != resolveSucceeded)
1084 /* for PUT* instructions we have to check the constraints on the value type */
1087 assert(fieldtyperef);
1089 /* check subtype constraints */
1090 result = resolve_lazy_subtype_checks(refmethod,
1092 CLASSREF_OR_CLASSINFO(fieldtyperef),
1093 resolveLinkageError);
1095 if (result != resolveSucceeded)
1099 /* impose loading constraint on field type */
1101 if (fi->type == TYPE_ADR) {
1102 assert(fieldtyperef);
1103 if (!classcache_add_constraint(declarer->classloader,
1104 referer->classloader,
1105 fieldtyperef->name))
1106 return resolveFailed;
1109 /* XXX impose loading constraint on instance? */
1112 return resolveSucceeded;
1114 #endif /* defined(ENABLE_VERIFIER) */
1116 /* resolve_field_lazy **********************************************************
1118 Resolve an unresolved field reference lazily
1120 NOTE: This function does NOT do any verification checks. In case of a
1121 successful resolution, you must call resolve_field_verifier_checks
1122 in order to perform the necessary checks!
1125 refmethod........the referer method
1126 fieldref.........the field reference
1129 resolveSucceeded.....the reference has been resolved
1130 resolveDeferred......the resolving could not be performed lazily
1131 resolveFailed........resolving failed, an exception has been thrown.
1133 *******************************************************************************/
1135 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1136 constant_FMIref *fieldref)
1139 classinfo *container;
1144 /* the class containing the reference */
1146 referer = refmethod->class;
1149 /* check if the field itself is already resolved */
1151 if (IS_FMIREF_RESOLVED(fieldref))
1152 return resolveSucceeded;
1154 /* first we must resolve the class containg the field */
1156 /* XXX can/may lazyResolving trigger linking? */
1158 if (!resolve_class_from_name(referer, refmethod,
1159 fieldref->p.classref->name, resolveLazy, true, true, &container))
1161 /* the class reference could not be resolved */
1162 return resolveFailed; /* exception */
1165 return resolveDeferred; /* be lazy */
1167 assert(container->state & CLASS_LINKED);
1169 /* now we must find the declaration of the field in `container`
1170 * or one of its superclasses */
1172 fi = class_resolvefield(container,
1173 fieldref->name, fieldref->descriptor,
1176 /* The field does not exist. But since we were called lazily, */
1177 /* this error must not be reported now. (It will be reported */
1178 /* if eager resolving of this field is ever tried.) */
1180 *exceptionptr = NULL;
1181 return resolveDeferred; /* be lazy */
1184 /* cache the result of the resolution */
1186 fieldref->p.field = fi;
1189 return resolveSucceeded;
1192 /* resolve_field ***************************************************************
1194 Resolve an unresolved field reference
1197 ref..............struct containing the reference
1198 mode.............mode of resolution:
1199 resolveLazy...only resolve if it does not
1200 require loading classes
1201 resolveEager..load classes if necessary
1204 *result..........set to the result of resolution, or to NULL if
1205 the reference has not been resolved
1206 In the case of an exception, *result is
1207 guaranteed to be set to NULL.
1210 true.............everything ok
1211 (*result may still be NULL for resolveLazy)
1212 false............an exception has been thrown
1214 *******************************************************************************/
1216 bool resolve_field(unresolved_field *ref,
1217 resolve_mode_t mode,
1221 classinfo *container;
1222 classinfo *declarer;
1223 constant_classref *fieldtyperef;
1225 resolve_result_t checkresult;
1229 assert(mode == resolveLazy || mode == resolveEager);
1233 #ifdef RESOLVE_VERBOSE
1234 unresolved_field_debug_dump(ref,stdout);
1237 /* the class containing the reference */
1239 referer = ref->referermethod->class;
1242 /* check if the field itself is already resolved */
1243 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1244 fi = ref->fieldref->p.field;
1245 container = fi->class;
1246 goto resolved_the_field;
1249 /* first we must resolve the class containg the field */
1250 if (!resolve_class_from_name(referer,ref->referermethod,
1251 ref->fieldref->p.classref->name,mode,true,true,&container))
1253 /* the class reference could not be resolved */
1254 return false; /* exception */
1257 return true; /* be lazy */
1260 assert(container->state & CLASS_LOADED);
1261 assert(container->state & CLASS_LINKED);
1263 /* now we must find the declaration of the field in `container`
1264 * or one of its superclasses */
1266 #ifdef RESOLVE_VERBOSE
1267 printf(" resolving field in class...\n");
1270 fi = class_resolvefield(container,
1271 ref->fieldref->name,ref->fieldref->descriptor,
1274 if (mode == resolveLazy) {
1275 /* The field does not exist. But since we were called lazily, */
1276 /* this error must not be reported now. (It will be reported */
1277 /* if eager resolving of this field is ever tried.) */
1279 *exceptionptr = NULL;
1280 return true; /* be lazy */
1283 return false; /* exception */
1286 /* cache the result of the resolution */
1287 ref->fieldref->p.field = fi;
1291 #ifdef ENABLE_VERIFIER
1292 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1293 /* that no missing parts of an instruction will be accessed. */
1295 checkresult = resolve_field_verifier_checks(
1300 NULL, /* instanceti, handled by constraints below */
1301 NULL, /* valueti, handled by constraints below */
1302 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1303 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1305 if (checkresult != resolveSucceeded)
1306 return (bool) checkresult;
1308 declarer = fi->class;
1310 assert(declarer->state & CLASS_LOADED);
1311 assert(declarer->state & CLASS_LINKED);
1313 /* for non-static accesses we have to check the constraints on the */
1316 if (!(ref->flags & RESOLVE_STATIC)) {
1317 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1318 &(ref->instancetypes),
1319 CLASSREF_OR_CLASSINFO(container),
1320 mode, resolveLinkageError);
1321 if (checkresult != resolveSucceeded)
1322 return (bool) checkresult;
1325 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1327 /* for PUT* instructions we have to check the constraints on the value type */
1328 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1329 assert(fieldtyperef);
1330 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1331 /* check subtype constraints */
1332 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1333 &(ref->valueconstraints),
1334 CLASSREF_OR_CLASSINFO(fieldtyperef),
1335 mode, resolveLinkageError);
1336 if (checkresult != resolveSucceeded)
1337 return (bool) checkresult;
1341 /* check protected access */
1342 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1343 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1344 &(ref->instancetypes),
1345 CLASSREF_OR_CLASSINFO(referer),
1347 resolveIllegalAccessError);
1348 if (checkresult != resolveSucceeded)
1349 return (bool) checkresult;
1353 #endif /* ENABLE_VERIFIER */
1361 /* resolve_field_eager *********************************************************
1363 Resolve an unresolved field reference eagerly.
1366 ref..............struct containing the reference
1369 fieldinfo * to the field, or
1370 NULL if an exception has been thrown
1372 *******************************************************************************/
1374 fieldinfo * resolve_field_eager(unresolved_field *ref)
1378 if (!resolve_field(ref,resolveEager,&fi))
1384 /******************************************************************************/
1385 /* METHOD RESOLUTION */
1386 /******************************************************************************/
1388 /* resolve_method_invokespecial_lookup *****************************************
1390 Do the special lookup for methods invoked by INVOKESPECIAL
1393 refmethod........the method containing the reference
1394 mi...............the methodinfo of the resolved method
1397 a methodinfo *...the result of the lookup,
1398 NULL.............an exception has been thrown
1400 *******************************************************************************/
1402 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1405 classinfo *declarer;
1411 /* get referer and declarer classes */
1413 referer = refmethod->class;
1416 declarer = mi->class;
1418 assert(referer->state & CLASS_LINKED);
1420 /* checks for INVOKESPECIAL: */
1421 /* for <init> and methods of the current class we don't need any */
1422 /* special checks. Otherwise we must verify that the called method */
1423 /* belongs to a super class of the current class */
1425 if ((referer != declarer) && (mi->name != utf_init)) {
1426 /* check that declarer is a super class of the current class */
1428 if (!class_issubclass(referer,declarer)) {
1429 exceptions_throw_verifyerror(refmethod,
1430 "INVOKESPECIAL calling non-super class method");
1434 /* if the referer has ACC_SUPER set, we must do the special */
1435 /* lookup starting with the direct super class of referer */
1437 if ((referer->flags & ACC_SUPER) != 0) {
1438 mi = class_resolvemethod(referer->super.cls,
1443 /* the spec calls for an AbstractMethodError in this case */
1444 exceptions_throw_abstractmethoderror();
1454 /* resolve_method_verifier_checks ******************************************
1456 Do the verifier checks necessary after a method has been resolved.
1459 refmethod........the method containing the reference
1460 methodref........the method reference
1461 mi...............the methodinfo of the resolved method
1462 invokestatic.....true if the method is invoked by INVOKESTATIC
1465 resolveSucceeded....everything ok
1466 resolveDeferred.....tests could not be done, have been deferred
1467 resolveFailed.......exception has been thrown
1469 *******************************************************************************/
1471 #if defined(ENABLE_VERIFIER)
1472 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1473 constant_FMIref *methodref,
1477 classinfo *declarer;
1484 #ifdef RESOLVE_VERBOSE
1485 printf("resolve_method_verifier_checks\n");
1486 printf(" flags: %02x\n",mi->flags);
1489 /* get the classinfos and the method descriptor */
1491 referer = refmethod->class;
1494 declarer = mi->class;
1499 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1500 /* a static method is accessed via an instance, or vice versa */
1502 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1503 (mi->flags & ACC_STATIC) ? "static method called via instance"
1504 : "instance method called without instance");
1505 return resolveFailed;
1508 /* check access rights */
1510 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1514 /* XXX clean this up. this should be in exceptions.c */
1515 msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
1516 utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
1517 message = MNEW(char, msglen);
1518 strcpy(message, "method is not accessible (");
1519 utf_cat_classname(message, declarer->name);
1520 strcat(message, ".");
1521 utf_cat(message, mi->name);
1522 utf_cat(message, mi->descriptor);
1523 strcat(message," from ");
1524 utf_cat_classname(message, referer->name);
1525 strcat(message,")");
1526 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1527 MFREE(message, char, msglen);
1528 return resolveFailed; /* exception */
1533 return resolveSucceeded;
1535 #endif /* defined(ENABLE_VERIFIER) */
1538 /* resolve_method_instance_type_checks *****************************************
1540 Check the instance type of a method invocation.
1543 refmethod........the method containing the reference
1544 mi...............the methodinfo of the resolved method
1545 instanceti.......typeinfo of the instance slot
1546 invokespecial....true if the method is invoked by INVOKESPECIAL
1549 resolveSucceeded....everything ok
1550 resolveDeferred.....tests could not be done, have been deferred
1551 resolveFailed.......exception has been thrown
1553 *******************************************************************************/
1555 #if defined(ENABLE_VERIFIER)
1556 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1558 typeinfo *instanceti,
1563 resolve_result_t result;
1565 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1566 { /* XXX clean up */
1567 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1568 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1569 : CLASSREF_OR_CLASSINFO(refmethod->class);
1571 if (!typeinfo_init_class(tip, initclass))
1578 result = resolve_lazy_subtype_checks(refmethod,
1580 CLASSREF_OR_CLASSINFO(mi->class),
1581 resolveLinkageError);
1582 if (result != resolveSucceeded)
1585 /* check protected access */
1587 /* XXX use other `declarer` than mi->class? */
1588 if (((mi->flags & ACC_PROTECTED) != 0)
1589 && !SAME_PACKAGE(mi->class, refmethod->class))
1591 result = resolve_lazy_subtype_checks(refmethod,
1593 CLASSREF_OR_CLASSINFO(refmethod->class),
1594 resolveIllegalAccessError);
1595 if (result != resolveSucceeded)
1601 return resolveSucceeded;
1603 #endif /* defined(ENABLE_VERIFIER) */
1606 /* resolve_method_param_type_checks ********************************************
1608 Check non-instance parameter types of a method invocation.
1611 jd...............jitdata of the method doing the call
1612 refmethod........the method containing the reference
1613 iptr.............the invoke instruction
1614 mi...............the methodinfo of the resolved method
1615 invokestatic.....true if the method is invoked by INVOKESTATIC
1618 resolveSucceeded....everything ok
1619 resolveDeferred.....tests could not be done, have been deferred
1620 resolveFailed.......exception has been thrown
1622 *******************************************************************************/
1624 #if defined(ENABLE_VERIFIER)
1625 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1626 methodinfo *refmethod,
1632 resolve_result_t result;
1634 typedesc *paramtypes;
1641 instancecount = (invokestatic) ? 0 : 1;
1643 /* check subtype constraints for TYPE_ADR parameters */
1645 md = mi->parseddesc;
1646 paramtypes = md->paramtypes;
1648 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1649 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1650 type = md->paramtypes[i+instancecount].type;
1653 assert(type == param->type);
1655 if (type == TYPE_ADR) {
1656 result = resolve_lazy_subtype_checks(refmethod,
1658 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1659 resolveLinkageError);
1660 if (result != resolveSucceeded)
1667 return resolveSucceeded;
1669 #endif /* defined(ENABLE_VERIFIER) */
1672 /* resolve_method_param_type_checks_stackbased *********************************
1674 Check non-instance parameter types of a method invocation.
1677 refmethod........the method containing the reference
1678 mi...............the methodinfo of the resolved method
1679 invokestatic.....true if the method is invoked by INVOKESTATIC
1680 stack............TOS before the INVOKE instruction
1683 resolveSucceeded....everything ok
1684 resolveDeferred.....tests could not be done, have been deferred
1685 resolveFailed.......exception has been thrown
1687 *******************************************************************************/
1689 #if defined(ENABLE_VERIFIER)
1690 resolve_result_t resolve_method_param_type_checks_stackbased(
1691 methodinfo *refmethod,
1694 typedescriptor *stack)
1696 typedescriptor *param;
1697 resolve_result_t result;
1699 typedesc *paramtypes;
1704 instancecount = (invokestatic) ? 0 : 1;
1706 /* check subtype constraints for TYPE_ADR parameters */
1708 md = mi->parseddesc;
1709 paramtypes = md->paramtypes;
1711 param = stack - (md->paramslots - 1 - instancecount);
1713 for (i = instancecount; i < md->paramcount; ++i) {
1714 type = md->paramtypes[i].type;
1716 assert(type == param->type);
1718 if (type == TYPE_ADR) {
1719 result = resolve_lazy_subtype_checks(refmethod,
1721 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1722 resolveLinkageError);
1723 if (result != resolveSucceeded)
1727 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1732 return resolveSucceeded;
1734 #endif /* defined(ENABLE_VERIFIER) */
1737 /* resolve_method_loading_constraints ******************************************
1739 Impose loading constraints on the parameters and return type of the
1743 referer..........the class refering to the method
1744 mi...............the method
1747 true................everything ok
1748 false...............an exception has been thrown
1750 *******************************************************************************/
1752 #if defined(ENABLE_VERIFIER)
1753 bool resolve_method_loading_constraints(classinfo *referer,
1757 typedesc *paramtypes;
1762 /* impose loading constraints on parameters (including instance) */
1764 md = mi->parseddesc;
1765 paramtypes = md->paramtypes;
1766 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1768 for (i = 0; i < md->paramcount; i++) {
1769 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1770 if (i < instancecount) {
1771 /* The type of the 'this' pointer is the class containing */
1772 /* the method definition. Since container is the same as, */
1773 /* or a subclass of declarer, we also constrain declarer */
1774 /* by transitivity of loading constraints. */
1775 name = mi->class->name;
1778 name = paramtypes[i].classref->name;
1781 /* The caller (referer) and the callee (container) must agree */
1782 /* on the types of the parameters. */
1783 if (!classcache_add_constraint(referer->classloader,
1784 mi->class->classloader, name))
1785 return false; /* exception */
1789 /* impose loading constraint onto return type */
1791 if (md->returntype.type == TYPE_ADR) {
1792 /* The caller (referer) and the callee (container) must agree */
1793 /* on the return type. */
1794 if (!classcache_add_constraint(referer->classloader,
1795 mi->class->classloader,
1796 md->returntype.classref->name))
1797 return false; /* exception */
1804 #endif /* defined(ENABLE_VERIFIER) */
1807 /* resolve_method_lazy *********************************************************
1809 Resolve an unresolved method reference lazily
1811 NOTE: This function does NOT do any verification checks. In case of a
1812 successful resolution, you must call resolve_method_verifier_checks
1813 in order to perform the necessary checks!
1816 refmethod........the referer method
1817 methodref........the method reference
1818 invokespecial....true if this is an INVOKESPECIAL instruction
1821 resolveSucceeded.....the reference has been resolved
1822 resolveDeferred......the resolving could not be performed lazily
1823 resolveFailed........resolving failed, an exception has been thrown.
1825 *******************************************************************************/
1827 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1828 constant_FMIref *methodref,
1832 classinfo *container;
1837 #ifdef RESOLVE_VERBOSE
1838 printf("resolve_method_lazy\n");
1841 /* the class containing the reference */
1843 referer = refmethod->class;
1846 /* check if the method itself is already resolved */
1848 if (IS_FMIREF_RESOLVED(methodref))
1849 return resolveSucceeded;
1851 /* first we must resolve the class containg the method */
1853 if (!resolve_class_from_name(referer, refmethod,
1854 methodref->p.classref->name, resolveLazy, true, true, &container))
1856 /* the class reference could not be resolved */
1857 return resolveFailed; /* exception */
1860 return resolveDeferred; /* be lazy */
1862 assert(container->state & CLASS_LINKED);
1864 /* now we must find the declaration of the method in `container`
1865 * or one of its superclasses */
1867 if (container->flags & ACC_INTERFACE) {
1868 mi = class_resolveinterfacemethod(container,
1870 methodref->descriptor,
1874 mi = class_resolveclassmethod(container,
1876 methodref->descriptor,
1881 /* The method does not exist. But since we were called lazily, */
1882 /* this error must not be reported now. (It will be reported */
1883 /* if eager resolving of this method is ever tried.) */
1885 *exceptionptr = NULL;
1886 return resolveDeferred; /* be lazy */
1889 if (invokespecial) {
1890 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1892 return resolveFailed; /* exception */
1895 /* have the method params already been parsed? no, do it. */
1897 if (!mi->parseddesc->params)
1898 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1899 return resolveFailed;
1901 /* cache the result of the resolution */
1903 methodref->p.method = mi;
1907 return resolveSucceeded;
1910 /* resolve_method **************************************************************
1912 Resolve an unresolved method reference
1915 ref..............struct containing the reference
1916 mode.............mode of resolution:
1917 resolveLazy...only resolve if it does not
1918 require loading classes
1919 resolveEager..load classes if necessary
1922 *result..........set to the result of resolution, or to NULL if
1923 the reference has not been resolved
1924 In the case of an exception, *result is
1925 guaranteed to be set to NULL.
1928 true.............everything ok
1929 (*result may still be NULL for resolveLazy)
1930 false............an exception has been thrown
1932 *******************************************************************************/
1934 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1937 classinfo *container;
1938 classinfo *declarer;
1940 typedesc *paramtypes;
1943 resolve_result_t checkresult;
1947 assert(mode == resolveLazy || mode == resolveEager);
1949 #ifdef RESOLVE_VERBOSE
1950 unresolved_method_debug_dump(ref,stdout);
1955 /* the class containing the reference */
1957 referer = ref->referermethod->class;
1960 /* check if the method itself is already resolved */
1962 if (IS_FMIREF_RESOLVED(ref->methodref)) {
1963 mi = ref->methodref->p.method;
1964 container = mi->class;
1965 goto resolved_the_method;
1968 /* first we must resolve the class containing the method */
1970 if (!resolve_class_from_name(referer,ref->referermethod,
1971 ref->methodref->p.classref->name,mode,true,true,&container))
1973 /* the class reference could not be resolved */
1974 return false; /* exception */
1977 return true; /* be lazy */
1980 assert(container->state & CLASS_LINKED);
1982 /* now we must find the declaration of the method in `container`
1983 * or one of its superclasses */
1985 if (container->flags & ACC_INTERFACE) {
1986 mi = class_resolveinterfacemethod(container,
1987 ref->methodref->name,
1988 ref->methodref->descriptor,
1992 mi = class_resolveclassmethod(container,
1993 ref->methodref->name,
1994 ref->methodref->descriptor,
1999 if (mode == resolveLazy) {
2000 /* The method does not exist. But since we were called lazily, */
2001 /* this error must not be reported now. (It will be reported */
2002 /* if eager resolving of this method is ever tried.) */
2004 *exceptionptr = NULL;
2005 return true; /* be lazy */
2008 return false; /* exception */ /* XXX set exceptionptr? */
2011 /* { the method reference has been resolved } */
2013 if (ref->flags & RESOLVE_SPECIAL) {
2014 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2016 return false; /* exception */
2019 /* have the method params already been parsed? no, do it. */
2021 if (!mi->parseddesc->params)
2022 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2025 /* cache the resolution */
2027 ref->methodref->p.method = mi;
2029 resolved_the_method:
2031 #ifdef ENABLE_VERIFIER
2034 checkresult = resolve_method_verifier_checks(
2038 (ref->flags & RESOLVE_STATIC));
2040 if (checkresult != resolveSucceeded)
2041 return (bool) checkresult;
2043 /* impose loading constraints on params and return type */
2045 if (!resolve_method_loading_constraints(referer, mi))
2048 declarer = mi->class;
2050 assert(referer->state & CLASS_LINKED);
2052 /* for non-static methods we have to check the constraints on the */
2055 if (!(ref->flags & RESOLVE_STATIC)) {
2056 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2057 &(ref->instancetypes),
2058 CLASSREF_OR_CLASSINFO(container),
2060 resolveLinkageError);
2061 if (checkresult != resolveSucceeded)
2062 return (bool) checkresult;
2069 /* check subtype constraints for TYPE_ADR parameters */
2071 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2072 paramtypes = mi->parseddesc->paramtypes;
2074 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2075 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2076 if (ref->paramconstraints) {
2077 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2078 ref->paramconstraints + i,
2079 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2081 resolveLinkageError);
2082 if (checkresult != resolveSucceeded)
2083 return (bool) checkresult;
2088 /* check protected access */
2090 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2092 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2093 &(ref->instancetypes),
2094 CLASSREF_OR_CLASSINFO(referer),
2096 resolveIllegalAccessError);
2097 if (checkresult != resolveSucceeded)
2098 return (bool) checkresult;
2101 #endif /* ENABLE_VERIFIER */
2108 /* resolve_method_eager ********************************************************
2110 Resolve an unresolved method reference eagerly.
2113 ref..............struct containing the reference
2116 methodinfo * to the method, or
2117 NULL if an exception has been thrown
2119 *******************************************************************************/
2121 methodinfo * resolve_method_eager(unresolved_method *ref)
2125 if (!resolve_method(ref,resolveEager,&mi))
2131 /******************************************************************************/
2132 /* CREATING THE DATA STRUCTURES */
2133 /******************************************************************************/
2135 #ifdef ENABLE_VERIFIER
2136 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2137 methodinfo *refmethod,
2138 unresolved_subtype_set *stset,
2140 utf *declaredclassname)
2148 #ifdef RESOLVE_VERBOSE
2149 printf("unresolved_subtype_set_from_typeinfo\n");
2150 #ifdef TYPEINFO_DEBUG
2151 typeinfo_print(stdout,tinfo,4);
2153 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2157 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2158 exceptions_throw_verifyerror(refmethod,
2159 "Invalid use of returnAddress");
2163 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2164 exceptions_throw_verifyerror(refmethod,
2165 "Invalid use of uninitialized object");
2169 /* the nulltype is always assignable */
2170 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2173 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2174 if (declaredclassname == utf_java_lang_Object
2175 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2180 if (tinfo->merged) {
2181 count = tinfo->merged->count;
2182 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2183 for (i=0; i<count; ++i) {
2184 classref_or_classinfo c = tinfo->merged->list[i];
2185 if (tinfo->dimension > 0) {
2186 /* a merge of array types */
2187 /* the merged list contains the possible _element_ types, */
2188 /* so we have to create array types with these elements. */
2189 if (IS_CLASSREF(c)) {
2190 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2193 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2196 stset->subtyperefs[i] = c;
2198 stset->subtyperefs[count].any = NULL; /* terminate */
2201 if ((IS_CLASSREF(tinfo->typeclass)
2202 ? tinfo->typeclass.ref->name
2203 : tinfo->typeclass.cls->name) == declaredclassname)
2205 /* the class names are the same */
2206 /* equality is guaranteed by the loading constraints */
2210 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2211 stset->subtyperefs[0] = tinfo->typeclass;
2212 stset->subtyperefs[1].any = NULL; /* terminate */
2219 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2222 #endif /* ENABLE_VERIFIER */
2224 /* create_unresolved_class *****************************************************
2226 Create an unresolved_class struct for the given class reference
2229 refmethod........the method triggering the resolution (if any)
2230 classref.........the class reference
2231 valuetype........value type to check against the resolved class
2232 may be NULL, if no typeinfo is available
2235 a pointer to a new unresolved_class struct, or
2236 NULL if an exception has been thrown
2238 *******************************************************************************/
2240 #ifdef ENABLE_VERIFIER
2241 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2242 constant_classref *classref,
2243 typeinfo *valuetype)
2245 unresolved_class *ref;
2247 #ifdef RESOLVE_VERBOSE
2248 printf("create_unresolved_class\n");
2249 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2251 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2252 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2254 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2257 ref = NEW(unresolved_class);
2258 ref->classref = classref;
2259 ref->referermethod = refmethod;
2262 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2263 &(ref->subtypeconstraints),valuetype,classref->name))
2267 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2272 #endif /* ENABLE_VERIFIER */
2274 /* resolve_create_unresolved_field *********************************************
2276 Create an unresolved_field struct for the given field access instruction
2279 referer..........the class containing the reference
2280 refmethod........the method triggering the resolution (if any)
2281 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2284 a pointer to a new unresolved_field struct, or
2285 NULL if an exception has been thrown
2287 *******************************************************************************/
2289 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2290 methodinfo *refmethod,
2293 unresolved_field *ref;
2294 constant_FMIref *fieldref = NULL;
2296 #ifdef RESOLVE_VERBOSE
2297 printf("create_unresolved_field\n");
2298 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2299 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2300 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2303 ref = NEW(unresolved_field);
2305 ref->referermethod = refmethod;
2306 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2308 switch (iptr->opc) {
2310 ref->flags |= RESOLVE_PUTFIELD;
2313 case ICMD_PUTFIELDCONST:
2314 ref->flags |= RESOLVE_PUTFIELD;
2317 case ICMD_PUTSTATIC:
2318 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2321 case ICMD_PUTSTATICCONST:
2322 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2328 case ICMD_GETSTATIC:
2329 ref->flags |= RESOLVE_STATIC;
2332 #if !defined(NDEBUG)
2338 fieldref = iptr->sx.s23.s3.fmiref;
2342 #ifdef RESOLVE_VERBOSE
2343 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2344 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2345 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2346 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2348 /*printf(" opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2351 ref->fieldref = fieldref;
2356 /* resolve_constrain_unresolved_field ******************************************
2358 Record subtype constraints for a field access.
2361 ref..............the unresolved_field structure of the access
2362 referer..........the class containing the reference
2363 refmethod........the method triggering the resolution (if any)
2364 instanceti.......instance typeinfo, if available
2365 valueti..........value typeinfo, if available
2368 true.............everything ok
2369 false............an exception has been thrown
2371 *******************************************************************************/
2373 #if defined(ENABLE_VERIFIER)
2374 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2376 methodinfo *refmethod,
2377 typeinfo *instanceti,
2380 constant_FMIref *fieldref;
2387 fieldref = ref->fieldref;
2390 #ifdef RESOLVE_VERBOSE
2391 printf("constrain_unresolved_field\n");
2392 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2393 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2394 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2395 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2396 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2397 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2398 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2400 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2403 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2404 fd = fieldref->parseddesc.fd;
2407 /* record subtype constraints for the instance type, if any */
2411 /* The instanceslot must contain a reference to a non-array type */
2412 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2413 exceptions_throw_verifyerror(refmethod,
2414 "illegal instruction: field access on non-reference");
2417 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2418 exceptions_throw_verifyerror(refmethod,
2419 "illegal instruction: field access on array");
2423 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2424 TYPEINFO_IS_NEWOBJECT(*instanceti))
2426 /* The instruction writes a field in an uninitialized object. */
2427 /* This is only allowed when a field of an uninitialized 'this' object is */
2428 /* written inside an initialization method */
2430 classinfo *initclass;
2431 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2434 exceptions_throw_verifyerror(refmethod,
2435 "accessing field of uninitialized object");
2438 /* XXX check that class of field == refmethod->class */
2439 initclass = refmethod->class; /* XXX classrefs */
2440 assert(initclass->state & CLASS_LOADED);
2441 assert(initclass->state & CLASS_LINKED);
2443 typeinfo_init_classinfo(&tinfo, initclass);
2447 insttip = instanceti;
2449 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2450 &(ref->instancetypes), insttip,
2451 FIELDREF_CLASSNAME(fieldref)))
2455 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2458 /* record subtype constraints for the value type, if any */
2460 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2462 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2463 &(ref->valueconstraints), valueti,
2464 fieldref->parseddesc.fd->classref->name))
2468 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2473 #endif /* ENABLE_VERIFIER */
2475 /* resolve_create_unresolved_method ********************************************
2477 Create an unresolved_method struct for the given method invocation
2480 referer..........the class containing the reference
2481 refmethod........the method triggering the resolution (if any)
2482 iptr.............the INVOKE* instruction
2485 a pointer to a new unresolved_method struct, or
2486 NULL if an exception has been thrown
2488 *******************************************************************************/
2490 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2491 methodinfo *refmethod,
2492 constant_FMIref *methodref,
2496 unresolved_method *ref;
2500 #ifdef RESOLVE_VERBOSE
2501 printf("create_unresolved_method\n");
2502 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2503 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2504 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2505 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2506 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2509 /* allocate params if necessary */
2510 if (!methodref->parseddesc.md->params)
2511 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2512 (invokestatic) ? ACC_STATIC : ACC_NONE))
2515 /* create the data structure */
2516 ref = NEW(unresolved_method);
2517 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2518 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2519 ref->referermethod = refmethod;
2520 ref->methodref = methodref;
2521 ref->paramconstraints = NULL;
2522 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2528 /* resolve_constrain_unresolved_method_instance ********************************
2530 Record subtype constraints for the instance argument of a method call.
2533 ref..............the unresolved_method structure of the call
2534 referer..........the class containing the reference
2535 refmethod........the method triggering the resolution (if any)
2536 iptr.............the INVOKE* instruction
2539 true.............everything ok
2540 false............an exception has been thrown
2542 *******************************************************************************/
2544 #if defined(ENABLE_VERIFIER)
2545 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2546 methodinfo *refmethod,
2547 typeinfo *instanceti,
2550 constant_FMIref *methodref;
2551 constant_classref *instanceref;
2556 methodref = ref->methodref;
2559 /* XXX clean this up */
2560 instanceref = IS_FMIREF_RESOLVED(methodref)
2561 ? class_get_self_classref(methodref->p.method->class)
2562 : methodref->p.classref;
2564 #ifdef RESOLVE_VERBOSE
2565 printf("resolve_constrain_unresolved_method_instance\n");
2566 printf(" rmethod: "); method_println(refmethod);
2567 printf(" mref : "); method_methodref_println(methodref);
2570 /* record subtype constraints for the instance type, if any */
2572 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2573 { /* XXX clean up */
2574 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2575 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2576 : CLASSREF_OR_CLASSINFO(refmethod->class);
2578 if (!typeinfo_init_class(tip, initclass))
2585 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2586 &(ref->instancetypes),tip,instanceref->name))
2591 #endif /* defined(ENABLE_VERIFIER) */
2594 /* resolve_constrain_unresolved_method_params *********************************
2596 Record subtype constraints for the non-instance arguments of a method call.
2599 jd...............current jitdata (for looking up variables)
2600 ref..............the unresolved_method structure of the call
2601 refmethod........the method triggering the resolution (if any)
2602 iptr.............the INVOKE* instruction
2605 true.............everything ok
2606 false............an exception has been thrown
2608 *******************************************************************************/
2610 #if defined(ENABLE_VERIFIER)
2611 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2612 unresolved_method *ref,
2613 methodinfo *refmethod,
2616 constant_FMIref *methodref;
2624 methodref = ref->methodref;
2626 md = methodref->parseddesc.md;
2628 assert(md->params != NULL);
2630 #ifdef RESOLVE_VERBOSE
2631 printf("resolve_constrain_unresolved_method_params\n");
2632 printf(" rmethod: "); method_println(refmethod);
2633 printf(" mref : "); method_methodref_println(methodref);
2634 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2637 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2639 /* record subtype constraints for the parameter types, if any */
2641 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2642 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2643 type = md->paramtypes[i+instancecount].type;
2646 assert(type == param->type);
2648 if (type == TYPE_ADR) {
2649 if (!ref->paramconstraints) {
2650 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2651 for (j=md->paramcount-1-instancecount; j>i; --j)
2652 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2654 assert(ref->paramconstraints);
2655 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2656 ref->paramconstraints + i,&(param->typeinfo),
2657 md->paramtypes[i+instancecount].classref->name))
2661 if (ref->paramconstraints)
2662 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2668 #endif /* ENABLE_VERIFIER */
2671 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2673 Record subtype constraints for the non-instance arguments of a method call.
2676 ref..............the unresolved_method structure of the call
2677 refmethod........the method triggering the resolution (if any)
2678 stack............TOS before the INVOKE instruction
2681 true.............everything ok
2682 false............an exception has been thrown
2684 *******************************************************************************/
2686 #if defined(ENABLE_VERIFIER)
2687 bool resolve_constrain_unresolved_method_params_stackbased(
2688 unresolved_method *ref,
2689 methodinfo *refmethod,
2690 typedescriptor *stack)
2692 constant_FMIref *methodref;
2693 typedescriptor *param;
2700 methodref = ref->methodref;
2702 md = methodref->parseddesc.md;
2704 assert(md->params != NULL);
2706 #ifdef RESOLVE_VERBOSE
2707 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2708 printf(" rmethod: "); method_println(refmethod);
2709 printf(" mref : "); method_methodref_println(methodref);
2712 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2714 /* record subtype constraints for the parameter types, if any */
2716 param = stack - (md->paramslots - 1 - instancecount);
2718 for (i = instancecount; i < md->paramcount; ++i) {
2719 type = md->paramtypes[i].type;
2721 assert(type == param->type);
2723 if (type == TYPE_ADR) {
2724 if (!ref->paramconstraints) {
2725 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2726 for (j = 0; j < i - instancecount; ++j)
2727 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2729 assert(ref->paramconstraints);
2730 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2731 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2732 md->paramtypes[i].classref->name))
2736 if (ref->paramconstraints)
2737 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2740 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2745 #endif /* ENABLE_VERIFIER */
2748 /******************************************************************************/
2749 /* FREEING MEMORY */
2750 /******************************************************************************/
2752 #ifdef ENABLE_VERIFIER
2753 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2756 classref_or_classinfo *p = list;
2758 /* this is silly. we *only* need to count the elements for MFREE */
2761 MFREE(list,classref_or_classinfo,(p - list));
2764 #endif /* ENABLE_VERIFIER */
2766 /* unresolved_class_free *******************************************************
2768 Free the memory used by an unresolved_class
2771 ref..............the unresolved_class
2773 *******************************************************************************/
2775 void unresolved_class_free(unresolved_class *ref)
2779 #ifdef ENABLE_VERIFIER
2780 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2782 FREE(ref,unresolved_class);
2785 /* unresolved_field_free *******************************************************
2787 Free the memory used by an unresolved_field
2790 ref..............the unresolved_field
2792 *******************************************************************************/
2794 void unresolved_field_free(unresolved_field *ref)
2798 #ifdef ENABLE_VERIFIER
2799 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2800 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2802 FREE(ref,unresolved_field);
2805 /* unresolved_method_free ******************************************************
2807 Free the memory used by an unresolved_method
2810 ref..............the unresolved_method
2812 *******************************************************************************/
2814 void unresolved_method_free(unresolved_method *ref)
2818 #ifdef ENABLE_VERIFIER
2819 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2820 if (ref->paramconstraints) {
2822 int count = ref->methodref->parseddesc.md->paramcount;
2824 for (i=0; i<count; ++i)
2825 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2826 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2829 FREE(ref,unresolved_method);
2832 /******************************************************************************/
2834 /******************************************************************************/
2836 #if !defined(NDEBUG)
2838 /* unresolved_subtype_set_debug_dump *******************************************
2840 Print debug info for unresolved_subtype_set to stream
2843 stset............the unresolved_subtype_set
2844 file.............the stream
2846 *******************************************************************************/
2848 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2850 classref_or_classinfo *p;
2852 if (SUBTYPESET_IS_EMPTY(*stset)) {
2853 fprintf(file," (empty)\n");
2856 p = stset->subtyperefs;
2857 for (;p->any; ++p) {
2858 if (IS_CLASSREF(*p)) {
2859 fprintf(file," ref: ");
2860 utf_fprint_printable_ascii(file,p->ref->name);
2863 fprintf(file," cls: ");
2864 utf_fprint_printable_ascii(file,p->cls->name);
2871 /* unresolved_class_debug_dump *************************************************
2873 Print debug info for unresolved_class to stream
2876 ref..............the unresolved_class
2877 file.............the stream
2879 *******************************************************************************/
2881 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2883 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2885 fprintf(file," referer : ");
2886 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2887 fprintf(file," refmethod : ");
2888 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2889 fprintf(file," refmethodd: ");
2890 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2891 fprintf(file," classname : ");
2892 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2893 fprintf(file," subtypeconstraints:\n");
2894 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2898 /* unresolved_field_debug_dump *************************************************
2900 Print debug info for unresolved_field to stream
2903 ref..............the unresolved_field
2904 file.............the stream
2906 *******************************************************************************/
2908 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2910 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2912 fprintf(file," referer : ");
2913 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2914 fprintf(file," refmethod : ");
2915 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2916 fprintf(file," refmethodd: ");
2917 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2918 fprintf(file," classname : ");
2919 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
2920 fprintf(file," name : ");
2921 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
2922 fprintf(file," descriptor: ");
2923 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
2924 fprintf(file," parseddesc: ");
2925 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2926 fprintf(file," flags : %04x\n",ref->flags);
2927 fprintf(file," instancetypes:\n");
2928 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2929 fprintf(file," valueconstraints:\n");
2930 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2934 /* unresolved_method_debug_dump ************************************************
2936 Print debug info for unresolved_method to stream
2939 ref..............the unresolved_method
2940 file.............the stream
2942 *******************************************************************************/
2944 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2948 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2950 fprintf(file," referer : ");
2951 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2952 fprintf(file," refmethod : ");
2953 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2954 fprintf(file," refmethodd: ");
2955 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2956 fprintf(file," classname : ");
2957 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
2958 fprintf(file," name : ");
2959 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
2960 fprintf(file," descriptor: ");
2961 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
2962 fprintf(file," parseddesc: ");
2963 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2964 fprintf(file," flags : %04x\n",ref->flags);
2965 fprintf(file," instancetypes:\n");
2966 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2967 fprintf(file," paramconstraints:\n");
2968 if (ref->paramconstraints) {
2969 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2970 fprintf(file," param %d:\n",i);
2971 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2975 fprintf(file," (empty)\n");
2979 #endif /* !defined(NDEBUG) */
2982 * These are local overrides for various environment variables in Emacs.
2983 * Please do not remove this and leave it at the end of the file, where
2984 * Emacs will automagically detect them.
2985 * ---------------------------------------------------------------------
2988 * indent-tabs-mode: t
2992 * vim:noexpandtab:sw=4:ts=4: