1 /* src/vm/resolve.c - resolving classes/interfaces/fields/methods
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Edwin Steiner
29 Changes: Christan Thalinger
31 $Id: resolve.c 3460 2005-10-20 09:34:16Z edwin $
38 #include "mm/memory.h"
39 #include "vm/resolve.h"
40 #include "vm/access.h"
41 #include "vm/classcache.h"
42 #include "vm/descriptor.h"
43 #include "vm/exceptions.h"
44 #include "vm/linker.h"
45 #include "vm/loader.h"
46 #include "vm/stringlocal.h"
47 #include "vm/jit/jit.h"
48 #include "vm/jit/verify/typeinfo.h"
51 /******************************************************************************/
53 /******************************************************************************/
55 /*#define RESOLVE_VERBOSE*/
57 /******************************************************************************/
58 /* CLASS RESOLUTION */
59 /******************************************************************************/
61 /* resolve_class_from_name *****************************************************
63 Resolve a symbolic class reference
66 referer..........the class containing the reference
67 refmethod........the method from which resolution was triggered
68 (may be NULL if not applicable)
69 classname........class name to resolve
70 mode.............mode of resolution:
71 resolveLazy...only resolve if it does not
72 require loading classes
73 resolveEager..load classes if necessary
74 checkaccess......if true, access rights to the class are checked
75 link.............if true, guarantee that the returned class, if any,
79 *result..........set to result of resolution, or to NULL if
80 the reference has not been resolved
81 In the case of an exception, *result is
82 guaranteed to be set to NULL.
85 true.............everything ok
86 (*result may still be NULL for resolveLazy)
87 false............an exception has been thrown
90 The returned class is *not* guaranteed to be linked!
91 (It is guaranteed to be loaded, though.)
93 *******************************************************************************/
95 bool resolve_class_from_name(classinfo *referer,
96 methodinfo *refmethod,
103 classinfo *cls = NULL;
110 assert(mode == resolveLazy || mode == resolveEager);
114 #ifdef RESOLVE_VERBOSE
115 fprintf(stderr,"resolve_class_from_name(");
116 utf_fprint(stderr,referer->name);
117 fprintf(stderr,",%p,",referer->classloader);
118 utf_fprint(stderr,classname);
119 fprintf(stderr,",%d,%d)\n",(int)checkaccess,(int)link);
122 /* lookup if this class has already been loaded */
124 cls = classcache_lookup(referer->classloader, classname);
126 #ifdef RESOLVE_VERBOSE
127 fprintf(stderr," lookup result: %p\n",(void*)cls);
131 /* resolve array types */
133 if (classname->text[0] == '[') {
134 utf_ptr = classname->text + 1;
135 len = classname->blength - 1;
137 /* classname is an array type name */
145 /* the component type is a reference type */
146 /* resolve the component type */
147 if (!resolve_class_from_name(referer,refmethod,
148 utf_new(utf_ptr,len),
149 mode,checkaccess,link,&cls))
150 return false; /* exception */
152 assert(mode == resolveLazy);
153 return true; /* be lazy */
155 /* create the array class */
156 cls = class_array_of(cls,false);
158 return false; /* exception */
162 /* the class has not been loaded, yet */
163 if (mode == resolveLazy)
164 return true; /* be lazy */
167 #ifdef RESOLVE_VERBOSE
168 fprintf(stderr," loading...\n");
173 if (!(cls = load_class_from_classloader(classname,
174 referer->classloader)))
175 return false; /* exception */
179 /* the class is now loaded */
183 #ifdef RESOLVE_VERBOSE
184 fprintf(stderr," checking access rights...\n");
187 /* check access rights of referer to refered class */
188 if (checkaccess && !access_is_accessible_class(referer,cls)) {
192 msglen = utf_strlen(cls->name) + utf_strlen(referer->name) + 100;
193 message = MNEW(char,msglen);
194 strcpy(message,"class is not accessible (");
195 utf_sprint_classname(message+strlen(message),cls->name);
196 strcat(message," from ");
197 utf_sprint_classname(message+strlen(message),referer->name);
199 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
200 MFREE(message,char,msglen);
201 return false; /* exception */
204 /* link the class if necessary */
207 if (!link_class(cls))
208 return false; /* exception */
212 /* resolution succeeds */
213 #ifdef RESOLVE_VERBOSE
214 fprintf(stderr," success.\n");
220 /* resolve_classref ************************************************************
222 Resolve a symbolic class reference
225 refmethod........the method from which resolution was triggered
226 (may be NULL if not applicable)
227 ref..............class reference
228 mode.............mode of resolution:
229 resolveLazy...only resolve if it does not
230 require loading classes
231 resolveEager..load classes if necessary
232 checkaccess......if true, access rights to the class are checked
233 link.............if true, guarantee that the returned class, if any,
237 *result..........set to result of resolution, or to NULL if
238 the reference has not been resolved
239 In the case of an exception, *result is
240 guaranteed to be set to NULL.
243 true.............everything ok
244 (*result may still be NULL for resolveLazy)
245 false............an exception has been thrown
247 *******************************************************************************/
249 bool resolve_classref(methodinfo *refmethod,
250 constant_classref *ref,
256 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
259 /* resolve_classref_or_classinfo ***********************************************
261 Resolve a symbolic class reference if necessary
264 refmethod........the method from which resolution was triggered
265 (may be NULL if not applicable)
266 cls..............class reference or classinfo
267 mode.............mode of resolution:
268 resolveLazy...only resolve if it does not
269 require loading classes
270 resolveEager..load classes if necessary
271 checkaccess......if true, access rights to the class are checked
272 link.............if true, guarantee that the returned class, if any,
276 *result..........set to result of resolution, or to NULL if
277 the reference has not been resolved
278 In the case of an exception, *result is
279 guaranteed to be set to NULL.
282 true.............everything ok
283 (*result may still be NULL for resolveLazy)
284 false............an exception has been thrown
286 *******************************************************************************/
288 bool resolve_classref_or_classinfo(methodinfo *refmethod,
289 classref_or_classinfo cls,
298 assert(mode == resolveEager || mode == resolveLazy);
301 #ifdef RESOLVE_VERBOSE
302 fprintf(stderr,"resolve_classref_or_classinfo(");
303 utf_fprint(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
304 fprintf(stderr,",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
309 if (IS_CLASSREF(cls)) {
310 /* we must resolve this reference */
312 if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
313 mode, checkaccess, link, &c))
314 goto return_exception;
317 /* cls has already been resolved */
321 assert(c || (mode == resolveLazy));
324 return true; /* be lazy */
332 goto return_exception;
347 /* resolve_class_from_typedesc *************************************************
349 Return a classinfo * for the given type descriptor
352 d................type descriptor
353 checkaccess......if true, access rights to the class are checked
354 link.............if true, guarantee that the returned class, if any,
357 *result..........set to result of resolution, or to NULL if
358 the reference has not been resolved
359 In the case of an exception, *result is
360 guaranteed to be set to NULL.
363 true.............everything ok
364 false............an exception has been thrown
367 This function always resolved eagerly.
369 *******************************************************************************/
371 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
380 #ifdef RESOLVE_VERBOSE
381 fprintf(stderr,"resolve_class_from_typedesc(");
382 descriptor_debug_print_typedesc(stderr,d);
383 fprintf(stderr,",%i,%i)\n",(int)checkaccess,(int)link);
387 /* a reference type */
388 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
389 resolveEager,checkaccess,link,&cls))
390 return false; /* exception */
393 /* a primitive type */
394 cls = primitivetype_table[d->decltype].class_primitive;
397 if (!link_class(cls))
398 return false; /* exception */
402 assert(!link || cls->linked);
404 #ifdef RESOLVE_VERBOSE
405 fprintf(stderr," result = ");utf_fprint(stderr,cls->name);fprintf(stderr,"\n");
412 /******************************************************************************/
413 /* SUBTYPE SET CHECKS */
414 /******************************************************************************/
416 /* resolve_and_check_subtype_set ***********************************************
418 Resolve the references in the given set and test subtype relationships
421 referer..........the class containing the references
422 refmethod........the method triggering the resolution
423 ref..............a set of class/interface references
425 type.............the type to test against the set
426 reversed.........if true, test if type is a subtype of
427 the set members, instead of the other
429 mode.............mode of resolution:
430 resolveLazy...only resolve if it does not
431 require loading classes
432 resolveEager..load classes if necessary
433 error............which type of exception to throw if
434 the test fails. May be:
435 resolveLinkageError, or
436 resolveIllegalAccessError
437 IMPORTANT: If error==resolveIllegalAccessError,
438 then array types in the set are skipped.
441 *checked.........set to true if all checks were performed,
442 otherwise set to false
443 (This is guaranteed to be true if mode was
444 resolveEager and no exception occured.)
445 If checked == NULL, this parameter is not used.
448 true.............the check succeeded
449 false............the check failed. An exception has been
453 The references in the set are resolved first, so any
454 exception which may occurr during resolution may
455 be thrown by this function.
457 *******************************************************************************/
459 bool resolve_and_check_subtype_set(classinfo *referer,methodinfo *refmethod,
460 unresolved_subtype_set *ref,
461 classref_or_classinfo typeref,
467 classref_or_classinfo *setp;
479 assert(mode == resolveLazy || mode == resolveEager);
480 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
482 #ifdef RESOLVE_VERBOSE
483 fprintf(stderr,"resolve_and_check_subtype_set\n");
484 unresolved_subtype_set_debug_dump(ref,stderr);
485 if (IS_CLASSREF(typeref)) {
486 fprintf(stderr," ref: ");utf_fprint(stderr,typeref.ref->name);
489 fprintf(stderr," cls: ");utf_fprint(stderr,typeref.cls->name);
491 fprintf(stderr,"\n");
494 setp = ref->subtyperefs;
496 /* an empty set of tests always succeeds */
497 if (!setp || !setp->any) {
506 /* first resolve the type if necessary */
507 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&type))
508 return false; /* exception */
510 return true; /* be lazy */
513 assert(type->loaded);
514 assert(type->linked);
515 TYPEINFO_INIT_CLASSINFO(typeti,type);
517 for (; setp->any; ++setp) {
518 /* first resolve the set member if necessary */
519 if (!resolve_classref_or_classinfo(refmethod,*setp,mode,false,true,&result)) {
520 /* the type could not be resolved. therefore we are sure that */
521 /* no instances of this type will ever exist -> skip this test */
522 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
523 *exceptionptr = NULL;
527 return true; /* be lazy */
530 assert(result->loaded);
531 assert(result->linked);
534 /* do not check access to protected members of arrays */
535 if (error == resolveIllegalAccessError && result->name->text[0] == '[') {
539 #ifdef RESOLVE_VERBOSE
540 fprintf(stderr,"performing subclass test:\n");
541 fprintf(stderr," ");utf_fprint(stderr,result->name);fputc('\n',stderr);
542 fprintf(stderr," must be a %s of\n",(reversed) ? "superclass" : "subclass");
543 fprintf(stderr," ");utf_fprint(stderr,type->name);fputc('\n',stderr);
546 /* now check the subtype relationship */
547 TYPEINFO_INIT_CLASSINFO(resultti,result);
549 /* we must test against `true` because `MAYBE` is also != 0 */
550 r = typeinfo_is_assignable_to_class(&typeti,CLASSREF_OR_CLASSINFO(result));
551 if (r == typecheck_FAIL)
553 if (r != typecheck_TRUE) {
554 #ifdef RESOLVE_VERBOSE
555 fprintf(stderr,"reversed subclass test failed\n");
561 /* we must test against `true` because `MAYBE` is also != 0 */
562 r = typeinfo_is_assignable_to_class(&resultti,CLASSREF_OR_CLASSINFO(type));
563 if (r == typecheck_FAIL)
565 if (r != typecheck_TRUE) {
566 #ifdef RESOLVE_VERBOSE
567 fprintf(stderr,"subclass test failed\n");
580 msglen = utf_strlen(result->name) + utf_strlen(type->name) + 200;
581 message = MNEW(char,msglen);
582 strcpy(message,(error == resolveIllegalAccessError) ?
583 "illegal access to protected member ("
584 : "subtype constraint violated (");
585 utf_sprint_classname(message+strlen(message),result->name);
586 strcat(message," is not a subclass of ");
587 utf_sprint_classname(message+strlen(message),type->name);
589 if (error == resolveIllegalAccessError)
590 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
592 *exceptionptr = new_exception_message(string_java_lang_LinkageError,message);
593 MFREE(message,char,msglen);
594 return false; /* exception */
597 /******************************************************************************/
598 /* CLASS RESOLUTION */
599 /******************************************************************************/
601 /* resolve_class ***************************************************************
603 Resolve an unresolved class reference. The class is also linked.
606 ref..............struct containing the reference
607 mode.............mode of resolution:
608 resolveLazy...only resolve if it does not
609 require loading classes
610 resolveEager..load classes if necessary
611 checkaccess......if true, access rights to the class are checked
614 *result..........set to the result of resolution, or to NULL if
615 the reference has not been resolved
616 In the case of an exception, *result is
617 guaranteed to be set to NULL.
620 true.............everything ok
621 (*result may still be NULL for resolveLazy)
622 false............an exception has been thrown
624 *******************************************************************************/
626 bool resolve_class(unresolved_class *ref,
636 assert(mode == resolveLazy || mode == resolveEager);
640 #ifdef RESOLVE_VERBOSE
641 unresolved_class_debug_dump(ref,stderr);
644 /* first we must resolve the class */
645 if (!resolve_classref(ref->referermethod,
646 ref->classref,mode,checkaccess,true,&cls))
648 /* the class reference could not be resolved */
649 return false; /* exception */
652 return true; /* be lazy */
655 assert(cls->loaded && cls->linked);
657 /* now we check the subtype constraints */
658 if (!resolve_and_check_subtype_set(ref->classref->referer,ref->referermethod,
659 &(ref->subtypeconstraints),
660 CLASSREF_OR_CLASSINFO(cls),
663 resolveLinkageError,&checked))
665 return false; /* exception */
668 return true; /* be lazy */
675 /* resolve_classref_eager ******************************************************
677 Resolve an unresolved class reference eagerly. The class is also linked and
678 access rights to the class are checked.
681 ref..............constant_classref to the class
684 classinfo * to the class, or
685 NULL if an exception has been thrown
687 *******************************************************************************/
689 classinfo * resolve_classref_eager(constant_classref *ref)
693 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
699 /* resolve_classref_eager_nonabstract ******************************************
701 Resolve an unresolved class reference eagerly. The class is also linked and
702 access rights to the class are checked. A check is performed that the class
706 ref..............constant_classref to the class
709 classinfo * to the class, or
710 NULL if an exception has been thrown
712 *******************************************************************************/
714 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
718 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
721 /* ensure that the class is not abstract */
723 if (c->flags & ACC_ABSTRACT) {
724 *exceptionptr = new_verifyerror(NULL,"creating instance of abstract class");
731 /* resolve_class_eager *********************************************************
733 Resolve an unresolved class reference eagerly. The class is also linked and
734 access rights to the class are checked.
737 ref..............struct containing the reference
740 classinfo * to the class, or
741 NULL if an exception has been thrown
743 *******************************************************************************/
745 classinfo * resolve_class_eager(unresolved_class *ref)
749 if (!resolve_class(ref,resolveEager,true,&c))
755 /******************************************************************************/
756 /* FIELD RESOLUTION */
757 /******************************************************************************/
759 /* resolve_field ***************************************************************
761 Resolve an unresolved field reference
764 ref..............struct containing the reference
765 mode.............mode of resolution:
766 resolveLazy...only resolve if it does not
767 require loading classes
768 resolveEager..load classes if necessary
771 *result..........set to the result of resolution, or to NULL if
772 the reference has not been resolved
773 In the case of an exception, *result is
774 guaranteed to be set to NULL.
777 true.............everything ok
778 (*result may still be NULL for resolveLazy)
779 false............an exception has been thrown
781 *******************************************************************************/
783 bool resolve_field(unresolved_field *ref,
788 classinfo *container;
790 constant_classref *fieldtyperef;
796 assert(mode == resolveLazy || mode == resolveEager);
800 #ifdef RESOLVE_VERBOSE
801 unresolved_field_debug_dump(ref,stderr);
804 /* the class containing the reference */
806 referer = ref->fieldref->classref->referer;
809 /* first we must resolve the class containg the field */
810 if (!resolve_class_from_name(referer,ref->referermethod,
811 ref->fieldref->classref->name,mode,true,true,&container))
813 /* the class reference could not be resolved */
814 return false; /* exception */
817 return true; /* be lazy */
820 assert(container->loaded && container->linked);
822 /* now we must find the declaration of the field in `container`
823 * or one of its superclasses */
825 #ifdef RESOLVE_VERBOSE
826 fprintf(stderr," resolving field in class...\n");
829 fi = class_resolvefield(container,
830 ref->fieldref->name,ref->fieldref->descriptor,
833 if (mode == resolveLazy) {
834 /* The field does not exist. But since we were called lazily, */
835 /* this error must not be reported now. (It will be reported */
836 /* if eager resolving of this field is ever tried.) */
838 *exceptionptr = NULL;
839 return true; /* be lazy */
842 return false; /* exception */
845 /* { the field reference has been resolved } */
846 declarer = fi->class;
848 assert(declarer->loaded && declarer->linked);
850 #ifdef RESOLVE_VERBOSE
851 fprintf(stderr," checking static...\n");
856 if (((fi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {
857 /* a static field is accessed via an instance, or vice versa */
858 *exceptionptr = new_exception_message(string_java_lang_IncompatibleClassChangeError,
859 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
860 : "instance field accessed without instance");
861 return false; /* exception */
864 /* for non-static accesses we have to check the constraints on the */
867 if (!(ref->flags & RESOLVE_STATIC)) {
868 #ifdef RESOLVE_VERBOSE
869 fprintf(stderr," checking instance types...\n");
872 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
873 &(ref->instancetypes),
874 CLASSREF_OR_CLASSINFO(container),
875 false, mode, resolveLinkageError,
878 return false; /* exception */
882 return true; /* be lazy */
885 #ifdef RESOLVE_VERBOSE
886 fprintf(stderr," checking instance types...done\n");
889 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
891 /* for PUT* instructions we have to check the constraints on the value type */
892 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
893 #ifdef RESOLVE_VERBOSE
894 fprintf(stderr," checking value constraints...\n");
896 assert(fieldtyperef);
897 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
898 /* check subtype constraints */
899 if (!resolve_and_check_subtype_set(referer, ref->referermethod,
900 &(ref->valueconstraints),
901 CLASSREF_OR_CLASSINFO(fieldtyperef),
902 false, mode, resolveLinkageError,
905 return false; /* exception */
908 return true; /* be lazy */
912 /* check access rights */
913 #ifdef RESOLVE_VERBOSE
914 fprintf(stderr," checking access rights...\n");
916 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
920 msglen = utf_strlen(declarer->name) + utf_strlen(fi->name) + utf_strlen(referer->name) + 100;
921 message = MNEW(char,msglen);
922 strcpy(message,"field is not accessible (");
923 utf_sprint_classname(message+strlen(message),declarer->name);
925 utf_sprint(message+strlen(message),fi->name);
926 strcat(message," from ");
927 utf_sprint_classname(message+strlen(message),referer->name);
929 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
930 MFREE(message,char,msglen);
931 return false; /* exception */
933 #ifdef RESOLVE_VERBOSE
934 fprintf(stderr," checking access rights...done\n");
935 fprintf(stderr," declarer = ");
936 utf_fprint_classname(stderr,declarer->name); fputc('\n',stderr);
937 fprintf(stderr," referer = ");
938 utf_fprint_classname(stderr,referer->name); fputc('\n',stderr);
941 /* check protected access */
942 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
943 #ifdef RESOLVE_VERBOSE
944 fprintf(stderr," checking protectec access...\n");
946 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
947 &(ref->instancetypes),
948 CLASSREF_OR_CLASSINFO(referer),
950 resolveIllegalAccessError, &checked))
952 return false; /* exception */
956 return true; /* be lazy */
959 /* impose loading constraint on field type */
961 if (fi->type == TYPE_ADR) {
962 #ifdef RESOLVE_VERBOSE
963 fprintf(stderr," adding constraint...\n");
965 assert(fieldtyperef);
966 if (!classcache_add_constraint(declarer->classloader,
967 referer->classloader,
973 #ifdef RESOLVE_VERBOSE
974 fprintf(stderr," success.\n");
981 /* resolve_field_eager *********************************************************
983 Resolve an unresolved field reference eagerly.
986 ref..............struct containing the reference
989 fieldinfo * to the field, or
990 NULL if an exception has been thrown
992 *******************************************************************************/
994 fieldinfo * resolve_field_eager(unresolved_field *ref)
998 if (!resolve_field(ref,resolveEager,&fi))
1004 /******************************************************************************/
1005 /* METHOD RESOLUTION */
1006 /******************************************************************************/
1008 /* resolve_method **************************************************************
1010 Resolve an unresolved method reference
1013 ref..............struct containing the reference
1014 mode.............mode of resolution:
1015 resolveLazy...only resolve if it does not
1016 require loading classes
1017 resolveEager..load classes if necessary
1020 *result..........set to the result of resolution, or to NULL if
1021 the reference has not been resolved
1022 In the case of an exception, *result is
1023 guaranteed to be set to NULL.
1026 true.............everything ok
1027 (*result may still be NULL for resolveLazy)
1028 false............an exception has been thrown
1030 *******************************************************************************/
1032 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1035 classinfo *container;
1036 classinfo *declarer;
1038 typedesc *paramtypes;
1045 assert(mode == resolveLazy || mode == resolveEager);
1047 #ifdef RESOLVE_VERBOSE
1048 unresolved_method_debug_dump(ref,stderr);
1053 /* the class containing the reference */
1054 referer = ref->methodref->classref->referer;
1057 /* first we must resolve the class containg the method */
1058 if (!resolve_class_from_name(referer,ref->referermethod,
1059 ref->methodref->classref->name,mode,true,true,&container))
1061 /* the class reference could not be resolved */
1062 return false; /* exception */
1065 return true; /* be lazy */
1068 assert(container->linked);
1070 /* now we must find the declaration of the method in `container`
1071 * or one of its superclasses */
1073 if (container->flags & ACC_INTERFACE) {
1074 mi = class_resolveinterfacemethod(container,
1075 ref->methodref->name,
1076 ref->methodref->descriptor,
1080 mi = class_resolveclassmethod(container,
1081 ref->methodref->name,
1082 ref->methodref->descriptor,
1087 if (mode == resolveLazy) {
1088 /* The method does not exist. But since we were called lazily, */
1089 /* this error must not be reported now. (It will be reported */
1090 /* if eager resolving of this method is ever tried.) */
1092 *exceptionptr = NULL;
1093 return true; /* be lazy */
1096 return false; /* exception */ /* XXX set exceptionptr? */
1099 #ifdef RESOLVE_VERBOSE
1100 fprintf(stderr," flags: %02x\n",mi->flags);
1102 /* { the method reference has been resolved } */
1104 declarer = mi->class;
1106 assert(referer->linked);
1108 /* checks for INVOKESPECIAL: */
1109 /* for <init> and methods of the current class we don't need any */
1110 /* special checks. Otherwise we must verify that the called method */
1111 /* belongs to a super class of the current class */
1112 if (((ref->flags & RESOLVE_SPECIAL) != 0)
1113 && referer != declarer
1114 && mi->name != utf_init)
1116 /* check that declarer is a super class of the current class */
1117 if (!class_issubclass(referer,declarer)) {
1118 *exceptionptr = new_verifyerror(ref->referermethod,
1119 "INVOKESPECIAL calling non-super class method");
1123 /* if the referer has ACC_SUPER set, we must do the special */
1124 /* lookup starting with the direct super class of referer */
1125 if ((referer->flags & ACC_SUPER) != 0) {
1126 mi = class_resolvemethod(referer->super.cls,
1127 ref->methodref->name,
1128 ref->methodref->descriptor);
1130 /* the spec calls for an AbstractMethodError in this case */
1131 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
1134 declarer = mi->class;
1140 if (((mi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {
1141 /* a static method is accessed via an instance, or vice versa */
1143 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1144 (mi->flags & ACC_STATIC) ? "static method called via instance"
1145 : "instance method called without instance");
1149 /* have the method params already been parsed? no, do it. */
1151 if (!mi->parseddesc->params)
1152 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1155 /* for non-static methods we have to check the constraints on the */
1158 if (!(ref->flags & RESOLVE_STATIC)) {
1159 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1160 &(ref->instancetypes),
1161 CLASSREF_OR_CLASSINFO(container),
1164 resolveLinkageError,&checked))
1166 return false; /* exception */
1169 return true; /* be lazy */
1176 /* check subtype constraints for TYPE_ADR parameters */
1178 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
1179 paramtypes = mi->parseddesc->paramtypes;
1181 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
1182 if (paramtypes[i+instancecount].type == TYPE_ADR) {
1183 if (ref->paramconstraints) {
1184 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1185 ref->paramconstraints + i,
1186 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1189 resolveLinkageError,&checked))
1191 return false; /* exception */
1194 return true; /* be lazy */
1199 /* check access rights */
1201 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1205 msglen = utf_strlen(declarer->name) + utf_strlen(mi->name) +
1206 utf_strlen(mi->descriptor) + utf_strlen(referer->name) + 100;
1207 message = MNEW(char,msglen);
1208 strcpy(message,"method is not accessible (");
1209 utf_sprint_classname(message+strlen(message),declarer->name);
1210 strcat(message,".");
1211 utf_sprint(message+strlen(message),mi->name);
1212 utf_sprint(message+strlen(message),mi->descriptor);
1213 strcat(message," from ");
1214 utf_sprint_classname(message+strlen(message),referer->name);
1215 strcat(message,")");
1216 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
1217 MFREE(message,char,msglen);
1218 return false; /* exception */
1221 /* check protected access */
1223 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1225 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1226 &(ref->instancetypes),
1227 CLASSREF_OR_CLASSINFO(referer),
1230 resolveIllegalAccessError,&checked))
1232 return false; /* exception */
1235 return true; /* be lazy */
1238 /* impose loading constraints on parameters (including instance) */
1240 paramtypes = mi->parseddesc->paramtypes;
1242 for (i = 0; i < mi->parseddesc->paramcount; i++) {
1243 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1246 if (i < instancecount)
1247 name = container->name; /* XXX should this be declarer->name? */
1249 name = paramtypes[i].classref->name;
1251 if (!classcache_add_constraint(referer->classloader,
1252 declarer->classloader, name))
1253 return false; /* exception */
1257 /* impose loading constraing onto return type */
1259 if (ref->methodref->parseddesc.md->returntype.type == TYPE_ADR) {
1260 if (!classcache_add_constraint(referer->classloader,declarer->classloader,
1261 ref->methodref->parseddesc.md->returntype.classref->name))
1262 return false; /* exception */
1270 /* resolve_method_eager ********************************************************
1272 Resolve an unresolved method reference eagerly.
1275 ref..............struct containing the reference
1278 methodinfo * to the method, or
1279 NULL if an exception has been thrown
1281 *******************************************************************************/
1283 methodinfo * resolve_method_eager(unresolved_method *ref)
1287 if (!resolve_method(ref,resolveEager,&mi))
1293 /******************************************************************************/
1294 /* CREATING THE DATA STRUCTURES */
1295 /******************************************************************************/
1297 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
1298 methodinfo *refmethod,
1299 unresolved_subtype_set *stset,
1301 constant_classref *declaredtype)
1309 #ifdef RESOLVE_VERBOSE
1310 fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
1311 #ifdef TYPEINFO_DEBUG
1312 typeinfo_print(stderr,tinfo,4);
1314 fprintf(stderr," declared type:");utf_fprint(stderr,declaredtype->name);
1315 fprintf(stderr,"\n");
1318 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
1319 *exceptionptr = new_verifyerror(refmethod,
1320 "Invalid use of returnAddress");
1324 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
1325 *exceptionptr = new_verifyerror(refmethod,
1326 "Invalid use of uninitialized object");
1330 /* the nulltype is always assignable (XXX for reversed?) */
1331 if (TYPEINFO_IS_NULLTYPE(*tinfo))
1334 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
1335 if (declaredtype->name == utf_java_lang_Object
1336 && referer->classloader == NULL)
1341 if (tinfo->merged) {
1342 count = tinfo->merged->count;
1343 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
1344 for (i=0; i<count; ++i) {
1345 classref_or_classinfo c = tinfo->merged->list[i];
1346 if (tinfo->dimension > 0) {
1347 /* a merge of array types */
1348 /* the merged list contains the possible _element_ types, */
1349 /* so we have to create array types with these elements. */
1350 if (IS_CLASSREF(c)) {
1351 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
1354 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
1357 stset->subtyperefs[i] = c;
1359 stset->subtyperefs[count].any = NULL; /* terminate */
1362 if ((IS_CLASSREF(tinfo->typeclass)
1363 ? tinfo->typeclass.ref->name
1364 : tinfo->typeclass.cls->name) == declaredtype->name)
1366 /* the class names are the same */
1367 /* equality is guaranteed by the loading constraints */
1371 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
1372 stset->subtyperefs[0] = tinfo->typeclass;
1373 stset->subtyperefs[1].any = NULL; /* terminate */
1380 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
1384 /* create_unresolved_class *****************************************************
1386 Create an unresolved_class struct for the given class reference
1389 refmethod........the method triggering the resolution (if any)
1390 classref.........the class reference
1391 valuetype........value type to check against the resolved class
1392 may be NULL, if no typeinfo is available
1395 a pointer to a new unresolved_class struct, or
1396 NULL if an exception has been thrown
1398 *******************************************************************************/
1400 unresolved_class * create_unresolved_class(methodinfo *refmethod,
1401 constant_classref *classref,
1402 typeinfo *valuetype)
1404 unresolved_class *ref;
1406 #ifdef RESOLVE_VERBOSE
1407 fprintf(stderr,"create_unresolved_class\n");
1408 fprintf(stderr," referer: ");utf_fprint(stderr,classref->referer->name);fputc('\n',stderr);
1410 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1411 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1413 fprintf(stderr," name : ");utf_fprint(stderr,classref->name);fputc('\n',stderr);
1416 ref = NEW(unresolved_class);
1417 ref->classref = classref;
1418 ref->referermethod = refmethod;
1421 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
1422 &(ref->subtypeconstraints),valuetype,classref))
1426 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
1432 /* create_unresolved_field *****************************************************
1434 Create an unresolved_field struct for the given field access instruction
1437 referer..........the class containing the reference
1438 refmethod........the method triggering the resolution (if any)
1439 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
1442 a pointer to a new unresolved_field struct, or
1443 NULL if an exception has been thrown
1445 *******************************************************************************/
1447 unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refmethod,
1450 unresolved_field *ref;
1451 constant_FMIref *fieldref = NULL;
1453 #ifdef RESOLVE_VERBOSE
1454 fprintf(stderr,"create_unresolved_field\n");
1455 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1456 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1457 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1460 ref = NEW(unresolved_field);
1462 ref->referermethod = refmethod;
1463 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
1465 switch (iptr[0].opc) {
1467 ref->flags |= RESOLVE_PUTFIELD;
1468 fieldref = (constant_FMIref *) iptr[0].val.a;
1471 case ICMD_PUTFIELDCONST:
1472 ref->flags |= RESOLVE_PUTFIELD;
1473 fieldref = (constant_FMIref *) iptr[1].val.a;
1476 case ICMD_PUTSTATIC:
1477 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
1478 fieldref = (constant_FMIref *) iptr[0].val.a;
1481 case ICMD_PUTSTATICCONST:
1482 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
1483 fieldref = (constant_FMIref *) iptr[1].val.a;
1487 fieldref = (constant_FMIref *) iptr[0].val.a;
1490 case ICMD_GETSTATIC:
1491 ref->flags |= RESOLVE_STATIC;
1492 fieldref = (constant_FMIref *) iptr[0].val.a;
1498 #ifdef RESOLVE_VERBOSE
1499 fprintf(stderr," class : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
1500 fprintf(stderr," name : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
1501 fprintf(stderr," desc : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
1502 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
1504 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1507 ref->fieldref = fieldref;
1512 /* constrain_unresolved_field **************************************************
1514 Record subtype constraints for a field access.
1517 ref..............the unresolved_field structure of the access
1518 referer..........the class containing the reference
1519 refmethod........the method triggering the resolution (if any)
1520 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
1521 stack............the input stack of the instruction
1524 true.............everything ok
1525 false............an exception has been thrown
1527 *******************************************************************************/
1529 bool constrain_unresolved_field(unresolved_field *ref,
1530 classinfo *referer, methodinfo *refmethod,
1532 stackelement *stack)
1534 constant_FMIref *fieldref;
1535 stackelement *instanceslot = NULL;
1538 typeinfo *tip = NULL;
1543 fieldref = ref->fieldref;
1546 #ifdef RESOLVE_VERBOSE
1547 fprintf(stderr,"constrain_unresolved_field\n");
1548 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1549 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1550 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1551 fprintf(stderr," class : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
1552 fprintf(stderr," name : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
1553 fprintf(stderr," desc : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
1554 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
1556 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1559 switch (iptr[0].opc) {
1561 instanceslot = stack->prev;
1562 tip = &(stack->typeinfo);
1565 case ICMD_PUTFIELDCONST:
1566 instanceslot = stack;
1569 case ICMD_PUTSTATIC:
1570 tip = &(stack->typeinfo);
1574 instanceslot = stack;
1578 assert(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
1579 fd = fieldref->parseddesc.fd;
1582 /* record subtype constraints for the instance type, if any */
1586 /* The instanceslot must contain a reference to a non-array type */
1587 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
1588 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1591 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
1592 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on array");
1596 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
1597 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1599 /* The instruction writes a field in an uninitialized object. */
1600 /* This is only allowed when a field of an uninitialized 'this' object is */
1601 /* written inside an initialization method */
1603 classinfo *initclass;
1604 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1607 *exceptionptr = new_verifyerror(refmethod,"accessing field of uninitialized object");
1610 /* XXX check that class of field == refmethod->class */
1611 initclass = refmethod->class; /* XXX classrefs */
1612 assert(initclass->loaded && initclass->linked);
1613 TYPEINFO_INIT_CLASSINFO(tinfo,initclass);
1617 insttip = &(instanceslot->typeinfo);
1619 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1620 &(ref->instancetypes),insttip,fieldref->classref))
1624 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1627 /* record subtype constraints for the value type, if any */
1629 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
1631 /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
1633 if (INSTRUCTION_PUTCONST_VALUE_ADR(iptr)) {
1634 assert(class_java_lang_String);
1635 assert(class_java_lang_String->loaded);
1636 assert(class_java_lang_String->linked);
1637 TYPEINFO_INIT_CLASSINFO(tinfo,class_java_lang_String);
1640 TYPEINFO_INIT_NULLTYPE(tinfo);
1642 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1643 &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref))
1647 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
1653 /* create_unresolved_method ****************************************************
1655 Create an unresolved_method struct for the given method invocation
1658 referer..........the class containing the reference
1659 refmethod........the method triggering the resolution (if any)
1660 iptr.............the INVOKE* instruction
1663 a pointer to a new unresolved_method struct, or
1664 NULL if an exception has been thrown
1666 *******************************************************************************/
1668 unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *refmethod,
1671 unresolved_method *ref;
1672 constant_FMIref *methodref;
1675 methodref = (constant_FMIref *) iptr[0].val.a;
1677 staticmethod = (iptr[0].opc == ICMD_INVOKESTATIC);
1679 #ifdef RESOLVE_VERBOSE
1680 fprintf(stderr,"create_unresolved_method\n");
1681 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1682 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1683 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1684 fprintf(stderr," class : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1685 fprintf(stderr," name : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1686 fprintf(stderr," desc : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1687 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1690 /* allocate params if necessary */
1691 if (!methodref->parseddesc.md->params)
1692 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
1693 (staticmethod) ? ACC_STATIC : ACC_NONE))
1696 /* create the data structure */
1697 ref = NEW(unresolved_method);
1698 ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
1699 | ((iptr[0].opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
1700 ref->referermethod = refmethod;
1701 ref->methodref = methodref;
1702 ref->paramconstraints = NULL;
1703 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1708 /* constrain_unresolved_method *************************************************
1710 Record subtype constraints for the arguments of a method call.
1713 ref..............the unresolved_method structure of the call
1714 referer..........the class containing the reference
1715 refmethod........the method triggering the resolution (if any)
1716 iptr.............the INVOKE* instruction
1717 stack............the input stack of the instruction
1720 true.............everything ok
1721 false............an exception has been thrown
1723 *******************************************************************************/
1725 bool constrain_unresolved_method(unresolved_method *ref,
1726 classinfo *referer, methodinfo *refmethod,
1728 stackelement *stack)
1730 constant_FMIref *methodref;
1731 stackelement *instanceslot = NULL;
1732 stackelement *param;
1740 methodref = ref->methodref;
1742 md = methodref->parseddesc.md;
1744 assert(md->params != NULL);
1746 #ifdef RESOLVE_VERBOSE
1747 fprintf(stderr,"constrain_unresolved_method\n");
1748 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1749 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1750 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1751 fprintf(stderr," class : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1752 fprintf(stderr," name : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1753 fprintf(stderr," desc : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1754 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1757 if ((ref->flags & RESOLVE_STATIC) == 0) {
1758 /* find the instance slot under all the parameter slots on the stack */
1759 instanceslot = stack;
1760 for (i=1; i<md->paramcount; ++i)
1761 instanceslot = instanceslot->prev;
1768 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
1770 /* record subtype constraints for the instance type, if any */
1774 assert(instanceslot->type == TYPE_ADR);
1776 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
1777 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1778 { /* XXX clean up */
1779 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1780 classref_or_classinfo initclass = (ins) ? CLASSREF_OR_CLASSINFO(ins[-1].val.a)
1781 : CLASSREF_OR_CLASSINFO(refmethod->class);
1783 if (!typeinfo_init_class(tip,initclass))
1787 tip = &(instanceslot->typeinfo);
1789 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1790 &(ref->instancetypes),tip,methodref->classref))
1794 /* record subtype constraints for the parameter types, if any */
1796 for (i=md->paramcount-1-instancecount; i>=0; --i, param=param->prev) {
1797 type = md->paramtypes[i+instancecount].type;
1800 assert(type == param->type);
1802 if (type == TYPE_ADR) {
1803 if (!ref->paramconstraints) {
1804 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
1805 for (j=md->paramcount-1-instancecount; j>i; --j)
1806 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
1808 assert(ref->paramconstraints);
1809 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1810 ref->paramconstraints + i,&(param->typeinfo),
1811 md->paramtypes[i+instancecount].classref))
1815 if (ref->paramconstraints)
1816 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
1823 /******************************************************************************/
1824 /* FREEING MEMORY */
1825 /******************************************************************************/
1827 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
1830 classref_or_classinfo *p = list;
1832 /* this is silly. we *only* need to count the elements for MFREE */
1835 MFREE(list,classref_or_classinfo,(p - list));
1839 /* unresolved_class_free *******************************************************
1841 Free the memory used by an unresolved_class
1844 ref..............the unresolved_class
1846 *******************************************************************************/
1848 void unresolved_class_free(unresolved_class *ref)
1852 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
1853 FREE(ref,unresolved_class);
1856 /* unresolved_field_free *******************************************************
1858 Free the memory used by an unresolved_field
1861 ref..............the unresolved_field
1863 *******************************************************************************/
1865 void unresolved_field_free(unresolved_field *ref)
1869 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1870 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
1871 FREE(ref,unresolved_field);
1874 /* unresolved_method_free ******************************************************
1876 Free the memory used by an unresolved_method
1879 ref..............the unresolved_method
1881 *******************************************************************************/
1883 void unresolved_method_free(unresolved_method *ref)
1887 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1888 if (ref->paramconstraints) {
1890 int count = ref->methodref->parseddesc.md->paramcount;
1892 for (i=0; i<count; ++i)
1893 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
1894 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
1896 FREE(ref,unresolved_method);
1900 /******************************************************************************/
1902 /******************************************************************************/
1904 /* unresolved_subtype_set_debug_dump *******************************************
1906 Print debug info for unresolved_subtype_set to stream
1909 stset............the unresolved_subtype_set
1910 file.............the stream
1912 *******************************************************************************/
1914 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
1916 classref_or_classinfo *p;
1918 if (SUBTYPESET_IS_EMPTY(*stset)) {
1919 fprintf(file," (empty)\n");
1922 p = stset->subtyperefs;
1923 for (;p->any; ++p) {
1924 if (IS_CLASSREF(*p)) {
1925 fprintf(file," ref: ");
1926 utf_fprint(file,p->ref->name);
1929 fprintf(file," cls: ");
1930 utf_fprint(file,p->cls->name);
1937 /* unresolved_class_debug_dump *************************************************
1939 Print debug info for unresolved_class to stream
1942 ref..............the unresolved_class
1943 file.............the stream
1945 *******************************************************************************/
1947 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
1949 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
1951 fprintf(file," referer : ");
1952 utf_fprint(file,ref->classref->referer->name); fputc('\n',file);
1953 fprintf(file," refmethod : ");
1954 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
1955 fprintf(file," refmethodd: ");
1956 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
1957 fprintf(file," classname : ");
1958 utf_fprint(file,ref->classref->name); fputc('\n',file);
1959 fprintf(file," subtypeconstraints:\n");
1960 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
1964 /* unresolved_field_debug_dump *************************************************
1966 Print debug info for unresolved_field to stream
1969 ref..............the unresolved_field
1970 file.............the stream
1972 *******************************************************************************/
1974 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
1976 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
1978 fprintf(file," referer : ");
1979 utf_fprint(file,ref->fieldref->classref->referer->name); fputc('\n',file);
1980 fprintf(file," refmethod : ");
1981 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
1982 fprintf(file," refmethodd: ");
1983 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
1984 fprintf(file," classname : ");
1985 utf_fprint(file,ref->fieldref->classref->name); fputc('\n',file);
1986 fprintf(file," name : ");
1987 utf_fprint(file,ref->fieldref->name); fputc('\n',file);
1988 fprintf(file," descriptor: ");
1989 utf_fprint(file,ref->fieldref->descriptor); fputc('\n',file);
1990 fprintf(file," parseddesc: ");
1991 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
1992 fprintf(file," flags : %04x\n",ref->flags);
1993 fprintf(file," instancetypes:\n");
1994 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
1995 fprintf(file," valueconstraints:\n");
1996 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2000 /* unresolved_method_debug_dump ************************************************
2002 Print debug info for unresolved_method to stream
2005 ref..............the unresolved_method
2006 file.............the stream
2008 *******************************************************************************/
2010 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2014 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2016 fprintf(file," referer : ");
2017 utf_fprint(file,ref->methodref->classref->referer->name); fputc('\n',file);
2018 fprintf(file," refmethod : ");
2019 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2020 fprintf(file," refmethodd: ");
2021 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2022 fprintf(file," classname : ");
2023 utf_fprint(file,ref->methodref->classref->name); fputc('\n',file);
2024 fprintf(file," name : ");
2025 utf_fprint(file,ref->methodref->name); fputc('\n',file);
2026 fprintf(file," descriptor: ");
2027 utf_fprint(file,ref->methodref->descriptor); fputc('\n',file);
2028 fprintf(file," parseddesc: ");
2029 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2030 fprintf(file," flags : %04x\n",ref->flags);
2031 fprintf(file," instancetypes:\n");
2032 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2033 fprintf(file," paramconstraints:\n");
2034 if (ref->paramconstraints) {
2035 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2036 fprintf(file," param %d:\n",i);
2037 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2041 fprintf(file," (empty)\n");
2048 * These are local overrides for various environment variables in Emacs.
2049 * Please do not remove this and leave it at the end of the file, where
2050 * Emacs will automagically detect them.
2051 * ---------------------------------------------------------------------
2054 * indent-tabs-mode: t
2058 * vim:noexpandtab:sw=4:ts=4: