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 6244 2006-12-27 15:15:31Z twisti $
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 #if defined(ENABLE_JAVASE)
1444 /* the spec calls for an AbstractMethodError in this case */
1445 exceptions_throw_abstractmethoderror();
1447 exceptions_throw_virtualmachineerror();
1458 /* resolve_method_verifier_checks ******************************************
1460 Do the verifier checks necessary after a method has been resolved.
1463 refmethod........the method containing the reference
1464 methodref........the method reference
1465 mi...............the methodinfo of the resolved method
1466 invokestatic.....true if the method is invoked by INVOKESTATIC
1469 resolveSucceeded....everything ok
1470 resolveDeferred.....tests could not be done, have been deferred
1471 resolveFailed.......exception has been thrown
1473 *******************************************************************************/
1475 #if defined(ENABLE_VERIFIER)
1476 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1477 constant_FMIref *methodref,
1481 classinfo *declarer;
1488 #ifdef RESOLVE_VERBOSE
1489 printf("resolve_method_verifier_checks\n");
1490 printf(" flags: %02x\n",mi->flags);
1493 /* get the classinfos and the method descriptor */
1495 referer = refmethod->class;
1498 declarer = mi->class;
1503 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1504 /* a static method is accessed via an instance, or vice versa */
1506 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1507 (mi->flags & ACC_STATIC) ? "static method called via instance"
1508 : "instance method called without instance");
1509 return resolveFailed;
1512 /* check access rights */
1514 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1518 /* XXX clean this up. this should be in exceptions.c */
1519 msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
1520 utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
1521 message = MNEW(char, msglen);
1522 strcpy(message, "method is not accessible (");
1523 utf_cat_classname(message, declarer->name);
1524 strcat(message, ".");
1525 utf_cat(message, mi->name);
1526 utf_cat(message, mi->descriptor);
1527 strcat(message," from ");
1528 utf_cat_classname(message, referer->name);
1529 strcat(message,")");
1530 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1531 MFREE(message, char, msglen);
1532 return resolveFailed; /* exception */
1537 return resolveSucceeded;
1539 #endif /* defined(ENABLE_VERIFIER) */
1542 /* resolve_method_instance_type_checks *****************************************
1544 Check the instance type of a method invocation.
1547 refmethod........the method containing the reference
1548 mi...............the methodinfo of the resolved method
1549 instanceti.......typeinfo of the instance slot
1550 invokespecial....true if the method is invoked by INVOKESPECIAL
1553 resolveSucceeded....everything ok
1554 resolveDeferred.....tests could not be done, have been deferred
1555 resolveFailed.......exception has been thrown
1557 *******************************************************************************/
1559 #if defined(ENABLE_VERIFIER)
1560 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1562 typeinfo *instanceti,
1567 resolve_result_t result;
1569 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1570 { /* XXX clean up */
1571 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1572 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1573 : CLASSREF_OR_CLASSINFO(refmethod->class);
1575 if (!typeinfo_init_class(tip, initclass))
1582 result = resolve_lazy_subtype_checks(refmethod,
1584 CLASSREF_OR_CLASSINFO(mi->class),
1585 resolveLinkageError);
1586 if (result != resolveSucceeded)
1589 /* check protected access */
1591 /* XXX use other `declarer` than mi->class? */
1592 if (((mi->flags & ACC_PROTECTED) != 0)
1593 && !SAME_PACKAGE(mi->class, refmethod->class))
1595 result = resolve_lazy_subtype_checks(refmethod,
1597 CLASSREF_OR_CLASSINFO(refmethod->class),
1598 resolveIllegalAccessError);
1599 if (result != resolveSucceeded)
1605 return resolveSucceeded;
1607 #endif /* defined(ENABLE_VERIFIER) */
1610 /* resolve_method_param_type_checks ********************************************
1612 Check non-instance parameter types of a method invocation.
1615 jd...............jitdata of the method doing the call
1616 refmethod........the method containing the reference
1617 iptr.............the invoke instruction
1618 mi...............the methodinfo of the resolved method
1619 invokestatic.....true if the method is invoked by INVOKESTATIC
1622 resolveSucceeded....everything ok
1623 resolveDeferred.....tests could not be done, have been deferred
1624 resolveFailed.......exception has been thrown
1626 *******************************************************************************/
1628 #if defined(ENABLE_VERIFIER)
1629 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1630 methodinfo *refmethod,
1636 resolve_result_t result;
1638 typedesc *paramtypes;
1645 instancecount = (invokestatic) ? 0 : 1;
1647 /* check subtype constraints for TYPE_ADR parameters */
1649 md = mi->parseddesc;
1650 paramtypes = md->paramtypes;
1652 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1653 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1654 type = md->paramtypes[i+instancecount].type;
1657 assert(type == param->type);
1659 if (type == TYPE_ADR) {
1660 result = resolve_lazy_subtype_checks(refmethod,
1662 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1663 resolveLinkageError);
1664 if (result != resolveSucceeded)
1671 return resolveSucceeded;
1673 #endif /* defined(ENABLE_VERIFIER) */
1676 /* resolve_method_param_type_checks_stackbased *********************************
1678 Check non-instance parameter types of a method invocation.
1681 refmethod........the method containing the reference
1682 mi...............the methodinfo of the resolved method
1683 invokestatic.....true if the method is invoked by INVOKESTATIC
1684 stack............TOS before the INVOKE instruction
1687 resolveSucceeded....everything ok
1688 resolveDeferred.....tests could not be done, have been deferred
1689 resolveFailed.......exception has been thrown
1691 *******************************************************************************/
1693 #if defined(ENABLE_VERIFIER)
1694 resolve_result_t resolve_method_param_type_checks_stackbased(
1695 methodinfo *refmethod,
1698 typedescriptor *stack)
1700 typedescriptor *param;
1701 resolve_result_t result;
1703 typedesc *paramtypes;
1708 instancecount = (invokestatic) ? 0 : 1;
1710 /* check subtype constraints for TYPE_ADR parameters */
1712 md = mi->parseddesc;
1713 paramtypes = md->paramtypes;
1715 param = stack - (md->paramslots - 1 - instancecount);
1717 for (i = instancecount; i < md->paramcount; ++i) {
1718 type = md->paramtypes[i].type;
1720 assert(type == param->type);
1722 if (type == TYPE_ADR) {
1723 result = resolve_lazy_subtype_checks(refmethod,
1725 CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
1726 resolveLinkageError);
1727 if (result != resolveSucceeded)
1731 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1736 return resolveSucceeded;
1738 #endif /* defined(ENABLE_VERIFIER) */
1741 /* resolve_method_loading_constraints ******************************************
1743 Impose loading constraints on the parameters and return type of the
1747 referer..........the class refering to the method
1748 mi...............the method
1751 true................everything ok
1752 false...............an exception has been thrown
1754 *******************************************************************************/
1756 #if defined(ENABLE_VERIFIER)
1757 bool resolve_method_loading_constraints(classinfo *referer,
1761 typedesc *paramtypes;
1766 /* impose loading constraints on parameters (including instance) */
1768 md = mi->parseddesc;
1769 paramtypes = md->paramtypes;
1770 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1772 for (i = 0; i < md->paramcount; i++) {
1773 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1774 if (i < instancecount) {
1775 /* The type of the 'this' pointer is the class containing */
1776 /* the method definition. Since container is the same as, */
1777 /* or a subclass of declarer, we also constrain declarer */
1778 /* by transitivity of loading constraints. */
1779 name = mi->class->name;
1782 name = paramtypes[i].classref->name;
1785 /* The caller (referer) and the callee (container) must agree */
1786 /* on the types of the parameters. */
1787 if (!classcache_add_constraint(referer->classloader,
1788 mi->class->classloader, name))
1789 return false; /* exception */
1793 /* impose loading constraint onto return type */
1795 if (md->returntype.type == TYPE_ADR) {
1796 /* The caller (referer) and the callee (container) must agree */
1797 /* on the return type. */
1798 if (!classcache_add_constraint(referer->classloader,
1799 mi->class->classloader,
1800 md->returntype.classref->name))
1801 return false; /* exception */
1808 #endif /* defined(ENABLE_VERIFIER) */
1811 /* resolve_method_lazy *********************************************************
1813 Resolve an unresolved method reference lazily
1815 NOTE: This function does NOT do any verification checks. In case of a
1816 successful resolution, you must call resolve_method_verifier_checks
1817 in order to perform the necessary checks!
1820 refmethod........the referer method
1821 methodref........the method reference
1822 invokespecial....true if this is an INVOKESPECIAL instruction
1825 resolveSucceeded.....the reference has been resolved
1826 resolveDeferred......the resolving could not be performed lazily
1827 resolveFailed........resolving failed, an exception has been thrown.
1829 *******************************************************************************/
1831 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1832 constant_FMIref *methodref,
1836 classinfo *container;
1841 #ifdef RESOLVE_VERBOSE
1842 printf("resolve_method_lazy\n");
1845 /* the class containing the reference */
1847 referer = refmethod->class;
1850 /* check if the method itself is already resolved */
1852 if (IS_FMIREF_RESOLVED(methodref))
1853 return resolveSucceeded;
1855 /* first we must resolve the class containg the method */
1857 if (!resolve_class_from_name(referer, refmethod,
1858 methodref->p.classref->name, resolveLazy, true, true, &container))
1860 /* the class reference could not be resolved */
1861 return resolveFailed; /* exception */
1864 return resolveDeferred; /* be lazy */
1866 assert(container->state & CLASS_LINKED);
1868 /* now we must find the declaration of the method in `container`
1869 * or one of its superclasses */
1871 if (container->flags & ACC_INTERFACE) {
1872 mi = class_resolveinterfacemethod(container,
1874 methodref->descriptor,
1878 mi = class_resolveclassmethod(container,
1880 methodref->descriptor,
1885 /* The method does not exist. But since we were called lazily, */
1886 /* this error must not be reported now. (It will be reported */
1887 /* if eager resolving of this method is ever tried.) */
1889 *exceptionptr = NULL;
1890 return resolveDeferred; /* be lazy */
1893 if (invokespecial) {
1894 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1896 return resolveFailed; /* exception */
1899 /* have the method params already been parsed? no, do it. */
1901 if (!mi->parseddesc->params)
1902 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1903 return resolveFailed;
1905 /* cache the result of the resolution */
1907 methodref->p.method = mi;
1911 return resolveSucceeded;
1914 /* resolve_method **************************************************************
1916 Resolve an unresolved method reference
1919 ref..............struct containing the reference
1920 mode.............mode of resolution:
1921 resolveLazy...only resolve if it does not
1922 require loading classes
1923 resolveEager..load classes if necessary
1926 *result..........set to the result of resolution, or to NULL if
1927 the reference has not been resolved
1928 In the case of an exception, *result is
1929 guaranteed to be set to NULL.
1932 true.............everything ok
1933 (*result may still be NULL for resolveLazy)
1934 false............an exception has been thrown
1936 *******************************************************************************/
1938 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1941 classinfo *container;
1942 classinfo *declarer;
1944 typedesc *paramtypes;
1947 resolve_result_t checkresult;
1951 assert(mode == resolveLazy || mode == resolveEager);
1953 #ifdef RESOLVE_VERBOSE
1954 unresolved_method_debug_dump(ref,stdout);
1959 /* the class containing the reference */
1961 referer = ref->referermethod->class;
1964 /* check if the method itself is already resolved */
1966 if (IS_FMIREF_RESOLVED(ref->methodref)) {
1967 mi = ref->methodref->p.method;
1968 container = mi->class;
1969 goto resolved_the_method;
1972 /* first we must resolve the class containing the method */
1974 if (!resolve_class_from_name(referer,ref->referermethod,
1975 ref->methodref->p.classref->name,mode,true,true,&container))
1977 /* the class reference could not be resolved */
1978 return false; /* exception */
1981 return true; /* be lazy */
1984 assert(container->state & CLASS_LINKED);
1986 /* now we must find the declaration of the method in `container`
1987 * or one of its superclasses */
1989 if (container->flags & ACC_INTERFACE) {
1990 mi = class_resolveinterfacemethod(container,
1991 ref->methodref->name,
1992 ref->methodref->descriptor,
1996 mi = class_resolveclassmethod(container,
1997 ref->methodref->name,
1998 ref->methodref->descriptor,
2003 if (mode == resolveLazy) {
2004 /* The method does not exist. But since we were called lazily, */
2005 /* this error must not be reported now. (It will be reported */
2006 /* if eager resolving of this method is ever tried.) */
2008 *exceptionptr = NULL;
2009 return true; /* be lazy */
2012 return false; /* exception */ /* XXX set exceptionptr? */
2015 /* { the method reference has been resolved } */
2017 if (ref->flags & RESOLVE_SPECIAL) {
2018 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2020 return false; /* exception */
2023 /* have the method params already been parsed? no, do it. */
2025 if (!mi->parseddesc->params)
2026 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2029 /* cache the resolution */
2031 ref->methodref->p.method = mi;
2033 resolved_the_method:
2035 #ifdef ENABLE_VERIFIER
2038 checkresult = resolve_method_verifier_checks(
2042 (ref->flags & RESOLVE_STATIC));
2044 if (checkresult != resolveSucceeded)
2045 return (bool) checkresult;
2047 /* impose loading constraints on params and return type */
2049 if (!resolve_method_loading_constraints(referer, mi))
2052 declarer = mi->class;
2054 assert(referer->state & CLASS_LINKED);
2056 /* for non-static methods we have to check the constraints on the */
2059 if (!(ref->flags & RESOLVE_STATIC)) {
2060 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2061 &(ref->instancetypes),
2062 CLASSREF_OR_CLASSINFO(container),
2064 resolveLinkageError);
2065 if (checkresult != resolveSucceeded)
2066 return (bool) checkresult;
2073 /* check subtype constraints for TYPE_ADR parameters */
2075 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2076 paramtypes = mi->parseddesc->paramtypes;
2078 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2079 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2080 if (ref->paramconstraints) {
2081 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2082 ref->paramconstraints + i,
2083 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2085 resolveLinkageError);
2086 if (checkresult != resolveSucceeded)
2087 return (bool) checkresult;
2092 /* check protected access */
2094 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2096 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2097 &(ref->instancetypes),
2098 CLASSREF_OR_CLASSINFO(referer),
2100 resolveIllegalAccessError);
2101 if (checkresult != resolveSucceeded)
2102 return (bool) checkresult;
2105 #endif /* ENABLE_VERIFIER */
2112 /* resolve_method_eager ********************************************************
2114 Resolve an unresolved method reference eagerly.
2117 ref..............struct containing the reference
2120 methodinfo * to the method, or
2121 NULL if an exception has been thrown
2123 *******************************************************************************/
2125 methodinfo * resolve_method_eager(unresolved_method *ref)
2129 if (!resolve_method(ref,resolveEager,&mi))
2135 /******************************************************************************/
2136 /* CREATING THE DATA STRUCTURES */
2137 /******************************************************************************/
2139 #ifdef ENABLE_VERIFIER
2140 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2141 methodinfo *refmethod,
2142 unresolved_subtype_set *stset,
2144 utf *declaredclassname)
2152 #ifdef RESOLVE_VERBOSE
2153 printf("unresolved_subtype_set_from_typeinfo\n");
2154 #ifdef TYPEINFO_DEBUG
2155 typeinfo_print(stdout,tinfo,4);
2157 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2161 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2162 exceptions_throw_verifyerror(refmethod,
2163 "Invalid use of returnAddress");
2167 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2168 exceptions_throw_verifyerror(refmethod,
2169 "Invalid use of uninitialized object");
2173 /* the nulltype is always assignable */
2174 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2177 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2178 if (declaredclassname == utf_java_lang_Object
2179 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2184 if (tinfo->merged) {
2185 count = tinfo->merged->count;
2186 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2187 for (i=0; i<count; ++i) {
2188 classref_or_classinfo c = tinfo->merged->list[i];
2189 if (tinfo->dimension > 0) {
2190 /* a merge of array types */
2191 /* the merged list contains the possible _element_ types, */
2192 /* so we have to create array types with these elements. */
2193 if (IS_CLASSREF(c)) {
2194 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2197 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2200 stset->subtyperefs[i] = c;
2202 stset->subtyperefs[count].any = NULL; /* terminate */
2205 if ((IS_CLASSREF(tinfo->typeclass)
2206 ? tinfo->typeclass.ref->name
2207 : tinfo->typeclass.cls->name) == declaredclassname)
2209 /* the class names are the same */
2210 /* equality is guaranteed by the loading constraints */
2214 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2215 stset->subtyperefs[0] = tinfo->typeclass;
2216 stset->subtyperefs[1].any = NULL; /* terminate */
2223 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2226 #endif /* ENABLE_VERIFIER */
2228 /* create_unresolved_class *****************************************************
2230 Create an unresolved_class struct for the given class reference
2233 refmethod........the method triggering the resolution (if any)
2234 classref.........the class reference
2235 valuetype........value type to check against the resolved class
2236 may be NULL, if no typeinfo is available
2239 a pointer to a new unresolved_class struct, or
2240 NULL if an exception has been thrown
2242 *******************************************************************************/
2244 #ifdef ENABLE_VERIFIER
2245 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2246 constant_classref *classref,
2247 typeinfo *valuetype)
2249 unresolved_class *ref;
2251 #ifdef RESOLVE_VERBOSE
2252 printf("create_unresolved_class\n");
2253 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2255 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2256 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2258 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2261 ref = NEW(unresolved_class);
2262 ref->classref = classref;
2263 ref->referermethod = refmethod;
2266 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2267 &(ref->subtypeconstraints),valuetype,classref->name))
2271 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2276 #endif /* ENABLE_VERIFIER */
2278 /* resolve_create_unresolved_field *********************************************
2280 Create an unresolved_field struct for the given field access instruction
2283 referer..........the class containing the reference
2284 refmethod........the method triggering the resolution (if any)
2285 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2288 a pointer to a new unresolved_field struct, or
2289 NULL if an exception has been thrown
2291 *******************************************************************************/
2293 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2294 methodinfo *refmethod,
2297 unresolved_field *ref;
2298 constant_FMIref *fieldref = NULL;
2300 #ifdef RESOLVE_VERBOSE
2301 printf("create_unresolved_field\n");
2302 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2303 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2304 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2307 ref = NEW(unresolved_field);
2309 ref->referermethod = refmethod;
2310 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2312 switch (iptr->opc) {
2314 ref->flags |= RESOLVE_PUTFIELD;
2317 case ICMD_PUTFIELDCONST:
2318 ref->flags |= RESOLVE_PUTFIELD;
2321 case ICMD_PUTSTATIC:
2322 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2325 case ICMD_PUTSTATICCONST:
2326 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2332 case ICMD_GETSTATIC:
2333 ref->flags |= RESOLVE_STATIC;
2336 #if !defined(NDEBUG)
2342 fieldref = iptr->sx.s23.s3.fmiref;
2346 #ifdef RESOLVE_VERBOSE
2347 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2348 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2349 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2350 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2354 ref->fieldref = fieldref;
2359 /* resolve_constrain_unresolved_field ******************************************
2361 Record subtype constraints for a field access.
2364 ref..............the unresolved_field structure of the access
2365 referer..........the class containing the reference
2366 refmethod........the method triggering the resolution (if any)
2367 instanceti.......instance typeinfo, if available
2368 valueti..........value typeinfo, if available
2371 true.............everything ok
2372 false............an exception has been thrown
2374 *******************************************************************************/
2376 #if defined(ENABLE_VERIFIER)
2377 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2379 methodinfo *refmethod,
2380 typeinfo *instanceti,
2383 constant_FMIref *fieldref;
2390 fieldref = ref->fieldref;
2393 #ifdef RESOLVE_VERBOSE
2394 printf("constrain_unresolved_field\n");
2395 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2396 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2397 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2398 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2399 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2400 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2401 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2405 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2406 fd = fieldref->parseddesc.fd;
2409 /* record subtype constraints for the instance type, if any */
2413 /* The instanceslot must contain a reference to a non-array type */
2414 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2415 exceptions_throw_verifyerror(refmethod,
2416 "illegal instruction: field access on non-reference");
2419 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2420 exceptions_throw_verifyerror(refmethod,
2421 "illegal instruction: field access on array");
2425 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2426 TYPEINFO_IS_NEWOBJECT(*instanceti))
2428 /* The instruction writes a field in an uninitialized object. */
2429 /* This is only allowed when a field of an uninitialized 'this' object is */
2430 /* written inside an initialization method */
2432 classinfo *initclass;
2433 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2436 exceptions_throw_verifyerror(refmethod,
2437 "accessing field of uninitialized object");
2440 /* XXX check that class of field == refmethod->class */
2441 initclass = refmethod->class; /* XXX classrefs */
2442 assert(initclass->state & CLASS_LOADED);
2443 assert(initclass->state & CLASS_LINKED);
2445 typeinfo_init_classinfo(&tinfo, initclass);
2449 insttip = instanceti;
2451 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2452 &(ref->instancetypes), insttip,
2453 FIELDREF_CLASSNAME(fieldref)))
2457 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2460 /* record subtype constraints for the value type, if any */
2462 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2464 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2465 &(ref->valueconstraints), valueti,
2466 fieldref->parseddesc.fd->classref->name))
2470 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2475 #endif /* ENABLE_VERIFIER */
2477 /* resolve_create_unresolved_method ********************************************
2479 Create an unresolved_method struct for the given method invocation
2482 referer..........the class containing the reference
2483 refmethod........the method triggering the resolution (if any)
2484 iptr.............the INVOKE* instruction
2487 a pointer to a new unresolved_method struct, or
2488 NULL if an exception has been thrown
2490 *******************************************************************************/
2492 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2493 methodinfo *refmethod,
2494 constant_FMIref *methodref,
2498 unresolved_method *ref;
2502 #ifdef RESOLVE_VERBOSE
2503 printf("create_unresolved_method\n");
2504 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2505 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2506 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2507 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2508 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2511 /* allocate params if necessary */
2512 if (!methodref->parseddesc.md->params)
2513 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2514 (invokestatic) ? ACC_STATIC : ACC_NONE))
2517 /* create the data structure */
2518 ref = NEW(unresolved_method);
2519 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2520 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2521 ref->referermethod = refmethod;
2522 ref->methodref = methodref;
2523 ref->paramconstraints = NULL;
2524 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2530 /* resolve_constrain_unresolved_method_instance ********************************
2532 Record subtype constraints for the instance argument of a method call.
2535 ref..............the unresolved_method structure of the call
2536 referer..........the class containing the reference
2537 refmethod........the method triggering the resolution (if any)
2538 iptr.............the INVOKE* instruction
2541 true.............everything ok
2542 false............an exception has been thrown
2544 *******************************************************************************/
2546 #if defined(ENABLE_VERIFIER)
2547 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2548 methodinfo *refmethod,
2549 typeinfo *instanceti,
2552 constant_FMIref *methodref;
2553 constant_classref *instanceref;
2558 methodref = ref->methodref;
2561 /* XXX clean this up */
2562 instanceref = IS_FMIREF_RESOLVED(methodref)
2563 ? class_get_self_classref(methodref->p.method->class)
2564 : methodref->p.classref;
2566 #ifdef RESOLVE_VERBOSE
2567 printf("resolve_constrain_unresolved_method_instance\n");
2568 printf(" rmethod: "); method_println(refmethod);
2569 printf(" mref : "); method_methodref_println(methodref);
2572 /* record subtype constraints for the instance type, if any */
2574 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
2575 { /* XXX clean up */
2576 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2577 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2578 : CLASSREF_OR_CLASSINFO(refmethod->class);
2580 if (!typeinfo_init_class(tip, initclass))
2587 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2588 &(ref->instancetypes),tip,instanceref->name))
2593 #endif /* defined(ENABLE_VERIFIER) */
2596 /* resolve_constrain_unresolved_method_params *********************************
2598 Record subtype constraints for the non-instance arguments of a method call.
2601 jd...............current jitdata (for looking up variables)
2602 ref..............the unresolved_method structure of the call
2603 refmethod........the method triggering the resolution (if any)
2604 iptr.............the INVOKE* instruction
2607 true.............everything ok
2608 false............an exception has been thrown
2610 *******************************************************************************/
2612 #if defined(ENABLE_VERIFIER)
2613 bool resolve_constrain_unresolved_method_params(jitdata *jd,
2614 unresolved_method *ref,
2615 methodinfo *refmethod,
2618 constant_FMIref *methodref;
2626 methodref = ref->methodref;
2628 md = methodref->parseddesc.md;
2630 assert(md->params != NULL);
2632 #ifdef RESOLVE_VERBOSE
2633 printf("resolve_constrain_unresolved_method_params\n");
2634 printf(" rmethod: "); method_println(refmethod);
2635 printf(" mref : "); method_methodref_println(methodref);
2638 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2640 /* record subtype constraints for the parameter types, if any */
2642 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2643 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2644 type = md->paramtypes[i+instancecount].type;
2647 assert(type == param->type);
2649 if (type == TYPE_ADR) {
2650 if (!ref->paramconstraints) {
2651 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2652 for (j=md->paramcount-1-instancecount; j>i; --j)
2653 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2655 assert(ref->paramconstraints);
2656 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2657 ref->paramconstraints + i,&(param->typeinfo),
2658 md->paramtypes[i+instancecount].classref->name))
2662 if (ref->paramconstraints)
2663 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2669 #endif /* ENABLE_VERIFIER */
2672 /* resolve_constrain_unresolved_method_params_stackbased ***********************
2674 Record subtype constraints for the non-instance arguments of a method call.
2677 ref..............the unresolved_method structure of the call
2678 refmethod........the method triggering the resolution (if any)
2679 stack............TOS before the INVOKE instruction
2682 true.............everything ok
2683 false............an exception has been thrown
2685 *******************************************************************************/
2687 #if defined(ENABLE_VERIFIER)
2688 bool resolve_constrain_unresolved_method_params_stackbased(
2689 unresolved_method *ref,
2690 methodinfo *refmethod,
2691 typedescriptor *stack)
2693 constant_FMIref *methodref;
2694 typedescriptor *param;
2701 methodref = ref->methodref;
2703 md = methodref->parseddesc.md;
2705 assert(md->params != NULL);
2707 #ifdef RESOLVE_VERBOSE
2708 printf("resolve_constrain_unresolved_method_params_stackbased\n");
2709 printf(" rmethod: "); method_println(refmethod);
2710 printf(" mref : "); method_methodref_println(methodref);
2713 instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2715 /* record subtype constraints for the parameter types, if any */
2717 param = stack - (md->paramslots - 1 - instancecount);
2719 for (i = instancecount; i < md->paramcount; ++i) {
2720 type = md->paramtypes[i].type;
2722 assert(type == param->type);
2724 if (type == TYPE_ADR) {
2725 if (!ref->paramconstraints) {
2726 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2727 for (j = 0; j < i - instancecount; ++j)
2728 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2730 assert(ref->paramconstraints);
2731 if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
2732 ref->paramconstraints + i - instancecount,&(param->typeinfo),
2733 md->paramtypes[i].classref->name))
2737 if (ref->paramconstraints)
2738 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2741 param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2746 #endif /* ENABLE_VERIFIER */
2749 /******************************************************************************/
2750 /* FREEING MEMORY */
2751 /******************************************************************************/
2753 #ifdef ENABLE_VERIFIER
2754 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2757 classref_or_classinfo *p = list;
2759 /* this is silly. we *only* need to count the elements for MFREE */
2762 MFREE(list,classref_or_classinfo,(p - list));
2765 #endif /* ENABLE_VERIFIER */
2767 /* unresolved_class_free *******************************************************
2769 Free the memory used by an unresolved_class
2772 ref..............the unresolved_class
2774 *******************************************************************************/
2776 void unresolved_class_free(unresolved_class *ref)
2780 #ifdef ENABLE_VERIFIER
2781 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2783 FREE(ref,unresolved_class);
2786 /* unresolved_field_free *******************************************************
2788 Free the memory used by an unresolved_field
2791 ref..............the unresolved_field
2793 *******************************************************************************/
2795 void unresolved_field_free(unresolved_field *ref)
2799 #ifdef ENABLE_VERIFIER
2800 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2801 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2803 FREE(ref,unresolved_field);
2806 /* unresolved_method_free ******************************************************
2808 Free the memory used by an unresolved_method
2811 ref..............the unresolved_method
2813 *******************************************************************************/
2815 void unresolved_method_free(unresolved_method *ref)
2819 #ifdef ENABLE_VERIFIER
2820 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2821 if (ref->paramconstraints) {
2823 int count = ref->methodref->parseddesc.md->paramcount;
2825 for (i=0; i<count; ++i)
2826 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2827 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2830 FREE(ref,unresolved_method);
2833 /******************************************************************************/
2835 /******************************************************************************/
2837 #if !defined(NDEBUG)
2839 /* unresolved_subtype_set_debug_dump *******************************************
2841 Print debug info for unresolved_subtype_set to stream
2844 stset............the unresolved_subtype_set
2845 file.............the stream
2847 *******************************************************************************/
2849 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2851 classref_or_classinfo *p;
2853 if (SUBTYPESET_IS_EMPTY(*stset)) {
2854 fprintf(file," (empty)\n");
2857 p = stset->subtyperefs;
2858 for (;p->any; ++p) {
2859 if (IS_CLASSREF(*p)) {
2860 fprintf(file," ref: ");
2861 utf_fprint_printable_ascii(file,p->ref->name);
2864 fprintf(file," cls: ");
2865 utf_fprint_printable_ascii(file,p->cls->name);
2872 /* unresolved_class_debug_dump *************************************************
2874 Print debug info for unresolved_class to stream
2877 ref..............the unresolved_class
2878 file.............the stream
2880 *******************************************************************************/
2882 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2884 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2886 fprintf(file," referer : ");
2887 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2888 fprintf(file," refmethod : ");
2889 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2890 fprintf(file," refmethodd: ");
2891 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2892 fprintf(file," classname : ");
2893 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2894 fprintf(file," subtypeconstraints:\n");
2895 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2899 /* unresolved_field_debug_dump *************************************************
2901 Print debug info for unresolved_field to stream
2904 ref..............the unresolved_field
2905 file.............the stream
2907 *******************************************************************************/
2909 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2911 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2913 fprintf(file," referer : ");
2914 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2915 fprintf(file," refmethod : ");
2916 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2917 fprintf(file," refmethodd: ");
2918 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2919 fprintf(file," classname : ");
2920 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
2921 fprintf(file," name : ");
2922 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
2923 fprintf(file," descriptor: ");
2924 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
2925 fprintf(file," parseddesc: ");
2926 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2927 fprintf(file," flags : %04x\n",ref->flags);
2928 fprintf(file," instancetypes:\n");
2929 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2930 fprintf(file," valueconstraints:\n");
2931 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2935 /* unresolved_method_debug_dump ************************************************
2937 Print debug info for unresolved_method to stream
2940 ref..............the unresolved_method
2941 file.............the stream
2943 *******************************************************************************/
2945 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2949 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2951 fprintf(file," referer : ");
2952 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2953 fprintf(file," refmethod : ");
2954 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2955 fprintf(file," refmethodd: ");
2956 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2957 fprintf(file," classname : ");
2958 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
2959 fprintf(file," name : ");
2960 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
2961 fprintf(file," descriptor: ");
2962 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
2963 fprintf(file," parseddesc: ");
2964 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2965 fprintf(file," flags : %04x\n",ref->flags);
2966 fprintf(file," instancetypes:\n");
2967 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2968 fprintf(file," paramconstraints:\n");
2969 if (ref->paramconstraints) {
2970 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2971 fprintf(file," param %d:\n",i);
2972 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2976 fprintf(file," (empty)\n");
2980 #endif /* !defined(NDEBUG) */
2983 * These are local overrides for various environment variables in Emacs.
2984 * Please do not remove this and leave it at the end of the file, where
2985 * Emacs will automagically detect them.
2986 * ---------------------------------------------------------------------
2989 * indent-tabs-mode: t
2993 * vim:noexpandtab:sw=4:ts=4: