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 3948 2005-12-20 12:59:22Z 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 */
181 assert(cls->state & CLASS_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 */
206 if (!(cls->state & CLASS_LINKED))
207 if (!link_class(cls))
208 return false; /* exception */
210 assert(cls->state & CLASS_LINKED);
213 /* resolution succeeds */
214 #ifdef RESOLVE_VERBOSE
215 fprintf(stderr," success.\n");
221 /* resolve_classref ************************************************************
223 Resolve a symbolic class reference
226 refmethod........the method from which resolution was triggered
227 (may be NULL if not applicable)
228 ref..............class reference
229 mode.............mode of resolution:
230 resolveLazy...only resolve if it does not
231 require loading classes
232 resolveEager..load classes if necessary
233 checkaccess......if true, access rights to the class are checked
234 link.............if true, guarantee that the returned class, if any,
238 *result..........set to result of resolution, or to NULL if
239 the reference has not been resolved
240 In the case of an exception, *result is
241 guaranteed to be set to NULL.
244 true.............everything ok
245 (*result may still be NULL for resolveLazy)
246 false............an exception has been thrown
248 *******************************************************************************/
250 bool resolve_classref(methodinfo *refmethod,
251 constant_classref *ref,
257 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
260 /* resolve_classref_or_classinfo ***********************************************
262 Resolve a symbolic class reference if necessary
265 refmethod........the method from which resolution was triggered
266 (may be NULL if not applicable)
267 cls..............class reference or classinfo
268 mode.............mode of resolution:
269 resolveLazy...only resolve if it does not
270 require loading classes
271 resolveEager..load classes if necessary
272 checkaccess......if true, access rights to the class are checked
273 link.............if true, guarantee that the returned class, if any,
277 *result..........set to result of resolution, or to NULL if
278 the reference has not been resolved
279 In the case of an exception, *result is
280 guaranteed to be set to NULL.
283 true.............everything ok
284 (*result may still be NULL for resolveLazy)
285 false............an exception has been thrown
287 *******************************************************************************/
289 bool resolve_classref_or_classinfo(methodinfo *refmethod,
290 classref_or_classinfo cls,
299 assert(mode == resolveEager || mode == resolveLazy);
302 #ifdef RESOLVE_VERBOSE
303 fprintf(stderr,"resolve_classref_or_classinfo(");
304 utf_fprint(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
305 fprintf(stderr,",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
310 if (IS_CLASSREF(cls)) {
311 /* we must resolve this reference */
313 if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
314 mode, checkaccess, link, &c))
315 goto return_exception;
318 /* cls has already been resolved */
320 assert(c->state & CLASS_LOADED);
322 assert(c || (mode == resolveLazy));
325 return true; /* be lazy */
328 assert(c->state & CLASS_LOADED);
331 if (!(c->state & CLASS_LINKED))
333 goto return_exception;
335 assert(c->state & CLASS_LINKED);
348 /* resolve_class_from_typedesc *************************************************
350 Return a classinfo * for the given type descriptor
353 d................type descriptor
354 checkaccess......if true, access rights to the class are checked
355 link.............if true, guarantee that the returned class, if any,
358 *result..........set to result of resolution, or to NULL if
359 the reference has not been resolved
360 In the case of an exception, *result is
361 guaranteed to be set to NULL.
364 true.............everything ok
365 false............an exception has been thrown
368 This function always resolved eagerly.
370 *******************************************************************************/
372 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
381 #ifdef RESOLVE_VERBOSE
382 fprintf(stderr,"resolve_class_from_typedesc(");
383 descriptor_debug_print_typedesc(stderr,d);
384 fprintf(stderr,",%i,%i)\n",(int)checkaccess,(int)link);
388 /* a reference type */
389 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
390 resolveEager,checkaccess,link,&cls))
391 return false; /* exception */
394 /* a primitive type */
395 cls = primitivetype_table[d->decltype].class_primitive;
396 assert(cls->state & CLASS_LOADED);
397 if (!(cls->state & CLASS_LINKED))
398 if (!link_class(cls))
399 return false; /* exception */
402 assert(cls->state & CLASS_LOADED);
403 assert(!link || (cls->state & CLASS_LINKED));
405 #ifdef RESOLVE_VERBOSE
406 fprintf(stderr," result = ");utf_fprint(stderr,cls->name);fprintf(stderr,"\n");
413 /******************************************************************************/
414 /* SUBTYPE SET CHECKS */
415 /******************************************************************************/
417 #ifdef ENABLE_VERIFIER
419 /* resolve_and_check_subtype_set ***********************************************
421 Resolve the references in the given set and test subtype relationships
424 referer..........the class containing the references
425 refmethod........the method triggering the resolution
426 ref..............a set of class/interface references
428 type.............the type to test against the set
429 reversed.........if true, test if type is a subtype of
430 the set members, instead of the other
432 mode.............mode of resolution:
433 resolveLazy...only resolve if it does not
434 require loading classes
435 resolveEager..load classes if necessary
436 error............which type of exception to throw if
437 the test fails. May be:
438 resolveLinkageError, or
439 resolveIllegalAccessError
440 IMPORTANT: If error==resolveIllegalAccessError,
441 then array types in the set are skipped.
444 *checked.........set to true if all checks were performed,
445 otherwise set to false
446 (This is guaranteed to be true if mode was
447 resolveEager and no exception occured.)
448 If checked == NULL, this parameter is not used.
451 true.............the check succeeded
452 false............the check failed. An exception has been
456 The references in the set are resolved first, so any
457 exception which may occurr during resolution may
458 be thrown by this function.
460 *******************************************************************************/
462 bool resolve_and_check_subtype_set(classinfo *referer,methodinfo *refmethod,
463 unresolved_subtype_set *ref,
464 classref_or_classinfo typeref,
470 classref_or_classinfo *setp;
482 assert(mode == resolveLazy || mode == resolveEager);
483 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
485 #ifdef RESOLVE_VERBOSE
486 fprintf(stderr,"resolve_and_check_subtype_set\n");
487 unresolved_subtype_set_debug_dump(ref,stderr);
488 if (IS_CLASSREF(typeref)) {
489 fprintf(stderr," ref: ");utf_fprint(stderr,typeref.ref->name);
492 fprintf(stderr," cls: ");utf_fprint(stderr,typeref.cls->name);
494 fprintf(stderr,"\n");
497 setp = ref->subtyperefs;
499 /* an empty set of tests always succeeds */
500 if (!setp || !setp->any) {
509 /* first resolve the type if necessary */
510 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&type))
511 return false; /* exception */
513 return true; /* be lazy */
516 assert(type->state & CLASS_LOADED);
517 assert(type->state & CLASS_LINKED);
518 typeinfo_init_classinfo(&typeti,type);
520 for (; setp->any; ++setp) {
521 /* first resolve the set member if necessary */
522 if (!resolve_classref_or_classinfo(refmethod,*setp,mode,false,true,&result)) {
523 /* the type could not be resolved. therefore we are sure that */
524 /* no instances of this type will ever exist -> skip this test */
525 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
526 *exceptionptr = NULL;
530 return true; /* be lazy */
533 assert(result->state & CLASS_LOADED);
534 assert(result->state & CLASS_LINKED);
537 /* do not check access to protected members of arrays */
538 if (error == resolveIllegalAccessError && result->name->text[0] == '[') {
542 #ifdef RESOLVE_VERBOSE
543 fprintf(stderr,"performing subclass test:\n");
544 fprintf(stderr," ");utf_fprint(stderr,result->name);fputc('\n',stderr);
545 fprintf(stderr," must be a %s of\n",(reversed) ? "superclass" : "subclass");
546 fprintf(stderr," ");utf_fprint(stderr,type->name);fputc('\n',stderr);
549 /* now check the subtype relationship */
550 typeinfo_init_classinfo(&resultti,result);
552 /* we must test against `true` because `MAYBE` is also != 0 */
553 r = typeinfo_is_assignable_to_class(&typeti,CLASSREF_OR_CLASSINFO(result));
554 if (r == typecheck_FAIL)
556 if (r != typecheck_TRUE) {
557 #ifdef RESOLVE_VERBOSE
558 fprintf(stderr,"reversed subclass test failed\n");
564 /* we must test against `true` because `MAYBE` is also != 0 */
565 r = typeinfo_is_assignable_to_class(&resultti,CLASSREF_OR_CLASSINFO(type));
566 if (r == typecheck_FAIL)
568 if (r != typecheck_TRUE) {
569 #ifdef RESOLVE_VERBOSE
570 fprintf(stderr,"subclass test failed\n");
583 msglen = utf_strlen(result->name) + utf_strlen(type->name) + 200;
584 message = MNEW(char,msglen);
585 strcpy(message,(error == resolveIllegalAccessError) ?
586 "illegal access to protected member ("
587 : "subtype constraint violated (");
588 utf_sprint_classname(message+strlen(message),result->name);
589 strcat(message," is not a subclass of ");
590 utf_sprint_classname(message+strlen(message),type->name);
592 if (error == resolveIllegalAccessError)
593 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
595 *exceptionptr = exceptions_new_linkageerror(message,NULL);
596 MFREE(message,char,msglen);
597 return false; /* exception */
600 #endif /* ENABLE_VERIFIER */
602 /******************************************************************************/
603 /* CLASS RESOLUTION */
604 /******************************************************************************/
606 /* resolve_class ***************************************************************
608 Resolve an unresolved class reference. The class is also linked.
611 ref..............struct containing the reference
612 mode.............mode of resolution:
613 resolveLazy...only resolve if it does not
614 require loading classes
615 resolveEager..load classes if necessary
616 checkaccess......if true, access rights to the class are checked
619 *result..........set to the result of resolution, or to NULL if
620 the reference has not been resolved
621 In the case of an exception, *result is
622 guaranteed to be set to NULL.
625 true.............everything ok
626 (*result may still be NULL for resolveLazy)
627 false............an exception has been thrown
629 *******************************************************************************/
631 #ifdef ENABLE_VERIFIER
632 bool resolve_class(unresolved_class *ref,
642 assert(mode == resolveLazy || mode == resolveEager);
646 #ifdef RESOLVE_VERBOSE
647 unresolved_class_debug_dump(ref,stderr);
650 /* first we must resolve the class */
651 if (!resolve_classref(ref->referermethod,
652 ref->classref,mode,checkaccess,true,&cls))
654 /* the class reference could not be resolved */
655 return false; /* exception */
658 return true; /* be lazy */
661 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
663 /* now we check the subtype constraints */
664 if (!resolve_and_check_subtype_set(ref->classref->referer,ref->referermethod,
665 &(ref->subtypeconstraints),
666 CLASSREF_OR_CLASSINFO(cls),
669 resolveLinkageError,&checked))
671 return false; /* exception */
674 return true; /* be lazy */
680 #endif /* ENABLE_VERIFIER */
682 /* resolve_classref_eager ******************************************************
684 Resolve an unresolved class reference eagerly. The class is also linked and
685 access rights to the class are checked.
688 ref..............constant_classref to the class
691 classinfo * to the class, or
692 NULL if an exception has been thrown
694 *******************************************************************************/
696 classinfo * resolve_classref_eager(constant_classref *ref)
700 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
706 /* resolve_classref_eager_nonabstract ******************************************
708 Resolve an unresolved class reference eagerly. The class is also linked and
709 access rights to the class are checked. A check is performed that the class
713 ref..............constant_classref to the class
716 classinfo * to the class, or
717 NULL if an exception has been thrown
719 *******************************************************************************/
721 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
725 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
728 /* ensure that the class is not abstract */
730 if (c->flags & ACC_ABSTRACT) {
731 *exceptionptr = new_verifyerror(NULL,"creating instance of abstract class");
738 /* resolve_class_eager *********************************************************
740 Resolve an unresolved class reference eagerly. The class is also linked and
741 access rights to the class are checked.
744 ref..............struct containing the reference
747 classinfo * to the class, or
748 NULL if an exception has been thrown
750 *******************************************************************************/
752 #ifdef ENABLE_VERIFIER
753 classinfo * resolve_class_eager(unresolved_class *ref)
757 if (!resolve_class(ref,resolveEager,true,&c))
762 #endif /* ENABLE_VERIFIER */
764 /******************************************************************************/
765 /* FIELD RESOLUTION */
766 /******************************************************************************/
768 /* resolve_field ***************************************************************
770 Resolve an unresolved field reference
773 ref..............struct containing the reference
774 mode.............mode of resolution:
775 resolveLazy...only resolve if it does not
776 require loading classes
777 resolveEager..load classes if necessary
780 *result..........set to the result of resolution, or to NULL if
781 the reference has not been resolved
782 In the case of an exception, *result is
783 guaranteed to be set to NULL.
786 true.............everything ok
787 (*result may still be NULL for resolveLazy)
788 false............an exception has been thrown
790 *******************************************************************************/
792 bool resolve_field(unresolved_field *ref,
797 classinfo *container;
799 constant_classref *fieldtyperef;
805 assert(mode == resolveLazy || mode == resolveEager);
809 #ifdef RESOLVE_VERBOSE
810 unresolved_field_debug_dump(ref,stderr);
813 /* the class containing the reference */
815 referer = ref->fieldref->classref->referer;
818 /* first we must resolve the class containg the field */
819 if (!resolve_class_from_name(referer,ref->referermethod,
820 ref->fieldref->classref->name,mode,true,true,&container))
822 /* the class reference could not be resolved */
823 return false; /* exception */
826 return true; /* be lazy */
829 assert(container->state & CLASS_LOADED);
830 assert(container->state & CLASS_LINKED);
832 /* now we must find the declaration of the field in `container`
833 * or one of its superclasses */
835 #ifdef RESOLVE_VERBOSE
836 fprintf(stderr," resolving field in class...\n");
839 fi = class_resolvefield(container,
840 ref->fieldref->name,ref->fieldref->descriptor,
843 if (mode == resolveLazy) {
844 /* The field does not exist. But since we were called lazily, */
845 /* this error must not be reported now. (It will be reported */
846 /* if eager resolving of this field is ever tried.) */
848 *exceptionptr = NULL;
849 return true; /* be lazy */
852 return false; /* exception */
855 #ifdef ENABLE_VERIFIER
857 /* { the field reference has been resolved } */
858 declarer = fi->class;
860 assert(declarer->state & CLASS_LOADED);
861 assert(declarer->state & CLASS_LINKED);
863 #ifdef RESOLVE_VERBOSE
864 fprintf(stderr," checking static...\n");
869 if (((fi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {
870 /* a static field is accessed via an instance, or vice versa */
871 *exceptionptr = new_exception_message(string_java_lang_IncompatibleClassChangeError,
872 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
873 : "instance field accessed without instance");
874 return false; /* exception */
877 /* for non-static accesses we have to check the constraints on the */
880 if (!(ref->flags & RESOLVE_STATIC)) {
881 #ifdef RESOLVE_VERBOSE
882 fprintf(stderr," checking instance types...\n");
885 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
886 &(ref->instancetypes),
887 CLASSREF_OR_CLASSINFO(container),
888 false, mode, resolveLinkageError,
891 return false; /* exception */
895 return true; /* be lazy */
898 #ifdef RESOLVE_VERBOSE
899 fprintf(stderr," checking instance types...done\n");
902 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
904 /* for PUT* instructions we have to check the constraints on the value type */
905 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
906 #ifdef RESOLVE_VERBOSE
907 fprintf(stderr," checking value constraints...\n");
909 assert(fieldtyperef);
910 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
911 /* check subtype constraints */
912 if (!resolve_and_check_subtype_set(referer, ref->referermethod,
913 &(ref->valueconstraints),
914 CLASSREF_OR_CLASSINFO(fieldtyperef),
915 false, mode, resolveLinkageError,
918 return false; /* exception */
921 return true; /* be lazy */
925 /* check access rights */
926 #ifdef RESOLVE_VERBOSE
927 fprintf(stderr," checking access rights...\n");
929 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
933 msglen = utf_strlen(declarer->name) + utf_strlen(fi->name) + utf_strlen(referer->name) + 100;
934 message = MNEW(char,msglen);
935 strcpy(message,"field is not accessible (");
936 utf_sprint_classname(message+strlen(message),declarer->name);
938 utf_sprint(message+strlen(message),fi->name);
939 strcat(message," from ");
940 utf_sprint_classname(message+strlen(message),referer->name);
942 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
943 MFREE(message,char,msglen);
944 return false; /* exception */
946 #ifdef RESOLVE_VERBOSE
947 fprintf(stderr," checking access rights...done\n");
948 fprintf(stderr," declarer = ");
949 utf_fprint_classname(stderr,declarer->name); fputc('\n',stderr);
950 fprintf(stderr," referer = ");
951 utf_fprint_classname(stderr,referer->name); fputc('\n',stderr);
954 /* check protected access */
955 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
956 #ifdef RESOLVE_VERBOSE
957 fprintf(stderr," checking protected access...\n");
959 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
960 &(ref->instancetypes),
961 CLASSREF_OR_CLASSINFO(referer),
963 resolveIllegalAccessError, &checked))
965 return false; /* exception */
969 return true; /* be lazy */
972 /* impose loading constraint on field type */
974 if (fi->type == TYPE_ADR) {
975 #ifdef RESOLVE_VERBOSE
976 fprintf(stderr," adding constraint...\n");
978 assert(fieldtyperef);
979 if (!classcache_add_constraint(declarer->classloader,
980 referer->classloader,
984 #endif /* ENABLE_VERIFIER */
987 #ifdef RESOLVE_VERBOSE
988 fprintf(stderr," success.\n");
995 /* resolve_field_eager *********************************************************
997 Resolve an unresolved field reference eagerly.
1000 ref..............struct containing the reference
1003 fieldinfo * to the field, or
1004 NULL if an exception has been thrown
1006 *******************************************************************************/
1008 fieldinfo * resolve_field_eager(unresolved_field *ref)
1012 if (!resolve_field(ref,resolveEager,&fi))
1018 /******************************************************************************/
1019 /* METHOD RESOLUTION */
1020 /******************************************************************************/
1022 /* resolve_method **************************************************************
1024 Resolve an unresolved method reference
1027 ref..............struct containing the reference
1028 mode.............mode of resolution:
1029 resolveLazy...only resolve if it does not
1030 require loading classes
1031 resolveEager..load classes if necessary
1034 *result..........set to the result of resolution, or to NULL if
1035 the reference has not been resolved
1036 In the case of an exception, *result is
1037 guaranteed to be set to NULL.
1040 true.............everything ok
1041 (*result may still be NULL for resolveLazy)
1042 false............an exception has been thrown
1044 *******************************************************************************/
1046 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1049 classinfo *container;
1050 classinfo *declarer;
1052 typedesc *paramtypes;
1059 assert(mode == resolveLazy || mode == resolveEager);
1061 #ifdef RESOLVE_VERBOSE
1062 unresolved_method_debug_dump(ref,stderr);
1067 /* the class containing the reference */
1068 referer = ref->methodref->classref->referer;
1071 /* first we must resolve the class containg the method */
1072 if (!resolve_class_from_name(referer,ref->referermethod,
1073 ref->methodref->classref->name,mode,true,true,&container))
1075 /* the class reference could not be resolved */
1076 return false; /* exception */
1079 return true; /* be lazy */
1082 assert(container->state & CLASS_LINKED);
1084 /* now we must find the declaration of the method in `container`
1085 * or one of its superclasses */
1087 if (container->flags & ACC_INTERFACE) {
1088 mi = class_resolveinterfacemethod(container,
1089 ref->methodref->name,
1090 ref->methodref->descriptor,
1094 mi = class_resolveclassmethod(container,
1095 ref->methodref->name,
1096 ref->methodref->descriptor,
1101 if (mode == resolveLazy) {
1102 /* The method does not exist. But since we were called lazily, */
1103 /* this error must not be reported now. (It will be reported */
1104 /* if eager resolving of this method is ever tried.) */
1106 *exceptionptr = NULL;
1107 return true; /* be lazy */
1110 return false; /* exception */ /* XXX set exceptionptr? */
1113 #ifdef ENABLE_VERIFIER
1115 #ifdef RESOLVE_VERBOSE
1116 fprintf(stderr," flags: %02x\n",mi->flags);
1118 /* { the method reference has been resolved } */
1120 declarer = mi->class;
1122 assert(referer->state & CLASS_LINKED);
1124 /* checks for INVOKESPECIAL: */
1125 /* for <init> and methods of the current class we don't need any */
1126 /* special checks. Otherwise we must verify that the called method */
1127 /* belongs to a super class of the current class */
1128 if (((ref->flags & RESOLVE_SPECIAL) != 0)
1129 && referer != declarer
1130 && mi->name != utf_init)
1132 /* check that declarer is a super class of the current class */
1133 if (!class_issubclass(referer,declarer)) {
1134 *exceptionptr = new_verifyerror(ref->referermethod,
1135 "INVOKESPECIAL calling non-super class method");
1139 /* if the referer has ACC_SUPER set, we must do the special */
1140 /* lookup starting with the direct super class of referer */
1141 if ((referer->flags & ACC_SUPER) != 0) {
1142 mi = class_resolvemethod(referer->super.cls,
1143 ref->methodref->name,
1144 ref->methodref->descriptor);
1146 /* the spec calls for an AbstractMethodError in this case */
1147 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
1150 declarer = mi->class;
1156 if (((mi->flags & ACC_STATIC) != 0) != ((ref->flags & RESOLVE_STATIC) != 0)) {
1157 /* a static method is accessed via an instance, or vice versa */
1159 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1160 (mi->flags & ACC_STATIC) ? "static method called via instance"
1161 : "instance method called without instance");
1165 /* have the method params already been parsed? no, do it. */
1167 if (!mi->parseddesc->params)
1168 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1171 /* for non-static methods we have to check the constraints on the */
1174 if (!(ref->flags & RESOLVE_STATIC)) {
1175 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1176 &(ref->instancetypes),
1177 CLASSREF_OR_CLASSINFO(container),
1180 resolveLinkageError,&checked))
1182 return false; /* exception */
1185 return true; /* be lazy */
1192 /* check subtype constraints for TYPE_ADR parameters */
1194 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
1195 paramtypes = mi->parseddesc->paramtypes;
1197 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
1198 if (paramtypes[i+instancecount].type == TYPE_ADR) {
1199 if (ref->paramconstraints) {
1200 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1201 ref->paramconstraints + i,
1202 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1205 resolveLinkageError,&checked))
1207 return false; /* exception */
1210 return true; /* be lazy */
1215 /* check access rights */
1217 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1221 msglen = utf_strlen(declarer->name) + utf_strlen(mi->name) +
1222 utf_strlen(mi->descriptor) + utf_strlen(referer->name) + 100;
1223 message = MNEW(char,msglen);
1224 strcpy(message,"method is not accessible (");
1225 utf_sprint_classname(message+strlen(message),declarer->name);
1226 strcat(message,".");
1227 utf_sprint(message+strlen(message),mi->name);
1228 utf_sprint(message+strlen(message),mi->descriptor);
1229 strcat(message," from ");
1230 utf_sprint_classname(message+strlen(message),referer->name);
1231 strcat(message,")");
1232 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
1233 MFREE(message,char,msglen);
1234 return false; /* exception */
1237 /* check protected access */
1239 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1241 if (!resolve_and_check_subtype_set(referer,ref->referermethod,
1242 &(ref->instancetypes),
1243 CLASSREF_OR_CLASSINFO(referer),
1246 resolveIllegalAccessError,&checked))
1248 return false; /* exception */
1251 return true; /* be lazy */
1254 /* impose loading constraints on parameters (including instance) */
1256 paramtypes = mi->parseddesc->paramtypes;
1258 for (i = 0; i < mi->parseddesc->paramcount; i++) {
1259 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1262 if (i < instancecount) {
1263 /* The type of the 'this' pointer is the class containing */
1264 /* the method definition. Since container is the same as, */
1265 /* or a subclass of declarer, we also constrain declarer */
1266 /* by transitivity of loading constraints. */
1267 name = container->name;
1270 name = paramtypes[i].classref->name;
1273 /* The caller (referer) and the callee (container) must agree */
1274 /* on the types of the parameters. */
1275 if (!classcache_add_constraint(referer->classloader,
1276 container->classloader, name))
1277 return false; /* exception */
1281 /* impose loading constraint onto return type */
1283 if (ref->methodref->parseddesc.md->returntype.type == TYPE_ADR) {
1284 /* The caller (referer) and the callee (container) must agree */
1285 /* on the return type. */
1286 if (!classcache_add_constraint(referer->classloader,container->classloader,
1287 ref->methodref->parseddesc.md->returntype.classref->name))
1288 return false; /* exception */
1291 #endif /* ENABLE_VERIFIER */
1298 /* resolve_method_eager ********************************************************
1300 Resolve an unresolved method reference eagerly.
1303 ref..............struct containing the reference
1306 methodinfo * to the method, or
1307 NULL if an exception has been thrown
1309 *******************************************************************************/
1311 methodinfo * resolve_method_eager(unresolved_method *ref)
1315 if (!resolve_method(ref,resolveEager,&mi))
1321 /******************************************************************************/
1322 /* CREATING THE DATA STRUCTURES */
1323 /******************************************************************************/
1325 #ifdef ENABLE_VERIFIER
1326 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
1327 methodinfo *refmethod,
1328 unresolved_subtype_set *stset,
1330 constant_classref *declaredtype)
1338 #ifdef RESOLVE_VERBOSE
1339 fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
1340 #ifdef TYPEINFO_DEBUG
1341 typeinfo_print(stderr,tinfo,4);
1343 fprintf(stderr," declared type:");utf_fprint(stderr,declaredtype->name);
1344 fprintf(stderr,"\n");
1347 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
1348 *exceptionptr = new_verifyerror(refmethod,
1349 "Invalid use of returnAddress");
1353 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
1354 *exceptionptr = new_verifyerror(refmethod,
1355 "Invalid use of uninitialized object");
1359 /* the nulltype is always assignable (XXX for reversed?) */
1360 if (TYPEINFO_IS_NULLTYPE(*tinfo))
1363 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
1364 if (declaredtype->name == utf_java_lang_Object
1365 && referer->classloader == NULL)
1370 if (tinfo->merged) {
1371 count = tinfo->merged->count;
1372 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
1373 for (i=0; i<count; ++i) {
1374 classref_or_classinfo c = tinfo->merged->list[i];
1375 if (tinfo->dimension > 0) {
1376 /* a merge of array types */
1377 /* the merged list contains the possible _element_ types, */
1378 /* so we have to create array types with these elements. */
1379 if (IS_CLASSREF(c)) {
1380 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
1383 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
1386 stset->subtyperefs[i] = c;
1388 stset->subtyperefs[count].any = NULL; /* terminate */
1391 if ((IS_CLASSREF(tinfo->typeclass)
1392 ? tinfo->typeclass.ref->name
1393 : tinfo->typeclass.cls->name) == declaredtype->name)
1395 /* the class names are the same */
1396 /* equality is guaranteed by the loading constraints */
1400 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
1401 stset->subtyperefs[0] = tinfo->typeclass;
1402 stset->subtyperefs[1].any = NULL; /* terminate */
1409 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
1412 #endif /* ENABLE_VERIFIER */
1414 /* create_unresolved_class *****************************************************
1416 Create an unresolved_class struct for the given class reference
1419 refmethod........the method triggering the resolution (if any)
1420 classref.........the class reference
1421 valuetype........value type to check against the resolved class
1422 may be NULL, if no typeinfo is available
1425 a pointer to a new unresolved_class struct, or
1426 NULL if an exception has been thrown
1428 *******************************************************************************/
1430 #ifdef ENABLE_VERIFIER
1431 unresolved_class * create_unresolved_class(methodinfo *refmethod,
1432 constant_classref *classref,
1433 typeinfo *valuetype)
1435 unresolved_class *ref;
1437 #ifdef RESOLVE_VERBOSE
1438 fprintf(stderr,"create_unresolved_class\n");
1439 fprintf(stderr," referer: ");utf_fprint(stderr,classref->referer->name);fputc('\n',stderr);
1441 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1442 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1444 fprintf(stderr," name : ");utf_fprint(stderr,classref->name);fputc('\n',stderr);
1447 ref = NEW(unresolved_class);
1448 ref->classref = classref;
1449 ref->referermethod = refmethod;
1452 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
1453 &(ref->subtypeconstraints),valuetype,classref))
1457 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
1462 #endif /* ENABLE_VERIFIER */
1464 /* create_unresolved_field *****************************************************
1466 Create an unresolved_field struct for the given field access instruction
1469 referer..........the class containing the reference
1470 refmethod........the method triggering the resolution (if any)
1471 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
1474 a pointer to a new unresolved_field struct, or
1475 NULL if an exception has been thrown
1477 *******************************************************************************/
1479 unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refmethod,
1482 unresolved_field *ref;
1483 constant_FMIref *fieldref = NULL;
1485 #ifdef RESOLVE_VERBOSE
1486 fprintf(stderr,"create_unresolved_field\n");
1487 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1488 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1489 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1492 ref = NEW(unresolved_field);
1494 ref->referermethod = refmethod;
1495 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
1497 switch (iptr[0].opc) {
1499 ref->flags |= RESOLVE_PUTFIELD;
1500 fieldref = (constant_FMIref *) iptr[0].val.a;
1503 case ICMD_PUTFIELDCONST:
1504 ref->flags |= RESOLVE_PUTFIELD;
1505 fieldref = (constant_FMIref *) iptr[1].val.a;
1508 case ICMD_PUTSTATIC:
1509 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
1510 fieldref = (constant_FMIref *) iptr[0].val.a;
1513 case ICMD_PUTSTATICCONST:
1514 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
1515 fieldref = (constant_FMIref *) iptr[1].val.a;
1519 fieldref = (constant_FMIref *) iptr[0].val.a;
1522 case ICMD_GETSTATIC:
1523 ref->flags |= RESOLVE_STATIC;
1524 fieldref = (constant_FMIref *) iptr[0].val.a;
1530 #ifdef RESOLVE_VERBOSE
1531 fprintf(stderr," class : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
1532 fprintf(stderr," name : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
1533 fprintf(stderr," desc : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
1534 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
1536 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1539 ref->fieldref = fieldref;
1544 /* constrain_unresolved_field **************************************************
1546 Record subtype constraints for a field access.
1549 ref..............the unresolved_field structure of the access
1550 referer..........the class containing the reference
1551 refmethod........the method triggering the resolution (if any)
1552 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
1553 stack............the input stack of the instruction
1556 true.............everything ok
1557 false............an exception has been thrown
1559 *******************************************************************************/
1561 #ifdef ENABLE_VERIFIER
1562 bool constrain_unresolved_field(unresolved_field *ref,
1563 classinfo *referer, methodinfo *refmethod,
1565 stackelement *stack)
1567 constant_FMIref *fieldref;
1568 stackelement *instanceslot = NULL;
1571 typeinfo *tip = NULL;
1576 fieldref = ref->fieldref;
1579 #ifdef RESOLVE_VERBOSE
1580 fprintf(stderr,"constrain_unresolved_field\n");
1581 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1582 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1583 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1584 fprintf(stderr," class : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
1585 fprintf(stderr," name : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
1586 fprintf(stderr," desc : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
1587 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
1589 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1592 switch (iptr[0].opc) {
1594 instanceslot = stack->prev;
1595 tip = &(stack->typeinfo);
1598 case ICMD_PUTFIELDCONST:
1599 instanceslot = stack;
1602 case ICMD_PUTSTATIC:
1603 tip = &(stack->typeinfo);
1607 instanceslot = stack;
1611 assert(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
1612 fd = fieldref->parseddesc.fd;
1615 /* record subtype constraints for the instance type, if any */
1619 /* The instanceslot must contain a reference to a non-array type */
1620 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
1621 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1624 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
1625 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on array");
1629 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
1630 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1632 /* The instruction writes a field in an uninitialized object. */
1633 /* This is only allowed when a field of an uninitialized 'this' object is */
1634 /* written inside an initialization method */
1636 classinfo *initclass;
1637 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1640 *exceptionptr = new_verifyerror(refmethod,"accessing field of uninitialized object");
1643 /* XXX check that class of field == refmethod->class */
1644 initclass = refmethod->class; /* XXX classrefs */
1645 assert(initclass->state & CLASS_LOADED);
1646 assert(initclass->state & CLASS_LINKED);
1648 typeinfo_init_classinfo(&tinfo,initclass);
1652 insttip = &(instanceslot->typeinfo);
1654 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1655 &(ref->instancetypes),insttip,fieldref->classref))
1659 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1662 /* record subtype constraints for the value type, if any */
1664 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
1666 /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
1668 if (INSTRUCTION_PUTCONST_VALUE_ADR(iptr)) {
1669 assert(class_java_lang_String);
1670 assert(class_java_lang_String->state & CLASS_LOADED);
1671 assert(class_java_lang_String->state & CLASS_LINKED);
1672 typeinfo_init_classinfo(&tinfo,class_java_lang_String);
1675 TYPEINFO_INIT_NULLTYPE(tinfo);
1677 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1678 &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref))
1682 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
1687 #endif /* ENABLE_VERIFIER */
1689 /* create_unresolved_method ****************************************************
1691 Create an unresolved_method struct for the given method invocation
1694 referer..........the class containing the reference
1695 refmethod........the method triggering the resolution (if any)
1696 iptr.............the INVOKE* instruction
1699 a pointer to a new unresolved_method struct, or
1700 NULL if an exception has been thrown
1702 *******************************************************************************/
1704 unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *refmethod,
1707 unresolved_method *ref;
1708 constant_FMIref *methodref;
1711 methodref = (constant_FMIref *) iptr[0].val.a;
1713 staticmethod = (iptr[0].opc == ICMD_INVOKESTATIC);
1715 #ifdef RESOLVE_VERBOSE
1716 fprintf(stderr,"create_unresolved_method\n");
1717 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1718 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1719 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1720 fprintf(stderr," class : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1721 fprintf(stderr," name : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1722 fprintf(stderr," desc : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1723 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1726 /* allocate params if necessary */
1727 if (!methodref->parseddesc.md->params)
1728 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
1729 (staticmethod) ? ACC_STATIC : ACC_NONE))
1732 /* create the data structure */
1733 ref = NEW(unresolved_method);
1734 ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
1735 | ((iptr[0].opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
1736 ref->referermethod = refmethod;
1737 ref->methodref = methodref;
1738 ref->paramconstraints = NULL;
1739 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
1744 /* constrain_unresolved_method *************************************************
1746 Record subtype constraints for the arguments of a method call.
1749 ref..............the unresolved_method structure of the call
1750 referer..........the class containing the reference
1751 refmethod........the method triggering the resolution (if any)
1752 iptr.............the INVOKE* instruction
1753 stack............the input stack of the instruction
1756 true.............everything ok
1757 false............an exception has been thrown
1759 *******************************************************************************/
1761 #ifdef ENABLE_VERIFIER
1762 bool constrain_unresolved_method(unresolved_method *ref,
1763 classinfo *referer, methodinfo *refmethod,
1765 stackelement *stack)
1767 constant_FMIref *methodref;
1768 stackelement *instanceslot = NULL;
1769 stackelement *param;
1777 methodref = ref->methodref;
1779 md = methodref->parseddesc.md;
1781 assert(md->params != NULL);
1783 #ifdef RESOLVE_VERBOSE
1784 fprintf(stderr,"constrain_unresolved_method\n");
1785 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
1786 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
1787 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
1788 fprintf(stderr," class : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
1789 fprintf(stderr," name : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
1790 fprintf(stderr," desc : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
1791 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
1794 if ((ref->flags & RESOLVE_STATIC) == 0) {
1795 /* find the instance slot under all the parameter slots on the stack */
1796 instanceslot = stack;
1797 for (i=1; i<md->paramcount; ++i)
1798 instanceslot = instanceslot->prev;
1805 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
1807 /* record subtype constraints for the instance type, if any */
1811 assert(instanceslot->type == TYPE_ADR);
1813 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
1814 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1815 { /* XXX clean up */
1816 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1817 classref_or_classinfo initclass = (ins) ? CLASSREF_OR_CLASSINFO(ins[-1].target)
1818 : CLASSREF_OR_CLASSINFO(refmethod->class);
1820 if (!typeinfo_init_class(tip,initclass))
1824 tip = &(instanceslot->typeinfo);
1826 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1827 &(ref->instancetypes),tip,methodref->classref))
1831 /* record subtype constraints for the parameter types, if any */
1833 for (i=md->paramcount-1-instancecount; i>=0; --i, param=param->prev) {
1834 type = md->paramtypes[i+instancecount].type;
1837 assert(type == param->type);
1839 if (type == TYPE_ADR) {
1840 if (!ref->paramconstraints) {
1841 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
1842 for (j=md->paramcount-1-instancecount; j>i; --j)
1843 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
1845 assert(ref->paramconstraints);
1846 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
1847 ref->paramconstraints + i,&(param->typeinfo),
1848 md->paramtypes[i+instancecount].classref))
1852 if (ref->paramconstraints)
1853 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
1859 #endif /* ENABLE_VERIFIER */
1861 /******************************************************************************/
1862 /* FREEING MEMORY */
1863 /******************************************************************************/
1865 #ifdef ENABLE_VERIFIER
1866 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
1869 classref_or_classinfo *p = list;
1871 /* this is silly. we *only* need to count the elements for MFREE */
1874 MFREE(list,classref_or_classinfo,(p - list));
1877 #endif /* ENABLE_VERIFIER */
1879 /* unresolved_class_free *******************************************************
1881 Free the memory used by an unresolved_class
1884 ref..............the unresolved_class
1886 *******************************************************************************/
1888 void unresolved_class_free(unresolved_class *ref)
1892 #ifdef ENABLE_VERIFIER
1893 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
1895 FREE(ref,unresolved_class);
1898 /* unresolved_field_free *******************************************************
1900 Free the memory used by an unresolved_field
1903 ref..............the unresolved_field
1905 *******************************************************************************/
1907 void unresolved_field_free(unresolved_field *ref)
1911 #ifdef ENABLE_VERIFIER
1912 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1913 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
1915 FREE(ref,unresolved_field);
1918 /* unresolved_method_free ******************************************************
1920 Free the memory used by an unresolved_method
1923 ref..............the unresolved_method
1925 *******************************************************************************/
1927 void unresolved_method_free(unresolved_method *ref)
1931 #ifdef ENABLE_VERIFIER
1932 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
1933 if (ref->paramconstraints) {
1935 int count = ref->methodref->parseddesc.md->paramcount;
1937 for (i=0; i<count; ++i)
1938 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
1939 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
1942 FREE(ref,unresolved_method);
1946 /******************************************************************************/
1948 /******************************************************************************/
1950 /* unresolved_subtype_set_debug_dump *******************************************
1952 Print debug info for unresolved_subtype_set to stream
1955 stset............the unresolved_subtype_set
1956 file.............the stream
1958 *******************************************************************************/
1960 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
1962 classref_or_classinfo *p;
1964 if (SUBTYPESET_IS_EMPTY(*stset)) {
1965 fprintf(file," (empty)\n");
1968 p = stset->subtyperefs;
1969 for (;p->any; ++p) {
1970 if (IS_CLASSREF(*p)) {
1971 fprintf(file," ref: ");
1972 utf_fprint(file,p->ref->name);
1975 fprintf(file," cls: ");
1976 utf_fprint(file,p->cls->name);
1983 /* unresolved_class_debug_dump *************************************************
1985 Print debug info for unresolved_class to stream
1988 ref..............the unresolved_class
1989 file.............the stream
1991 *******************************************************************************/
1993 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
1995 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
1997 fprintf(file," referer : ");
1998 utf_fprint(file,ref->classref->referer->name); fputc('\n',file);
1999 fprintf(file," refmethod : ");
2000 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2001 fprintf(file," refmethodd: ");
2002 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2003 fprintf(file," classname : ");
2004 utf_fprint(file,ref->classref->name); fputc('\n',file);
2005 fprintf(file," subtypeconstraints:\n");
2006 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2010 /* unresolved_field_debug_dump *************************************************
2012 Print debug info for unresolved_field to stream
2015 ref..............the unresolved_field
2016 file.............the stream
2018 *******************************************************************************/
2020 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2022 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2024 fprintf(file," referer : ");
2025 utf_fprint(file,ref->fieldref->classref->referer->name); fputc('\n',file);
2026 fprintf(file," refmethod : ");
2027 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2028 fprintf(file," refmethodd: ");
2029 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2030 fprintf(file," classname : ");
2031 utf_fprint(file,ref->fieldref->classref->name); fputc('\n',file);
2032 fprintf(file," name : ");
2033 utf_fprint(file,ref->fieldref->name); fputc('\n',file);
2034 fprintf(file," descriptor: ");
2035 utf_fprint(file,ref->fieldref->descriptor); fputc('\n',file);
2036 fprintf(file," parseddesc: ");
2037 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2038 fprintf(file," flags : %04x\n",ref->flags);
2039 fprintf(file," instancetypes:\n");
2040 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2041 fprintf(file," valueconstraints:\n");
2042 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2046 /* unresolved_method_debug_dump ************************************************
2048 Print debug info for unresolved_method to stream
2051 ref..............the unresolved_method
2052 file.............the stream
2054 *******************************************************************************/
2056 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2060 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2062 fprintf(file," referer : ");
2063 utf_fprint(file,ref->methodref->classref->referer->name); fputc('\n',file);
2064 fprintf(file," refmethod : ");
2065 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2066 fprintf(file," refmethodd: ");
2067 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2068 fprintf(file," classname : ");
2069 utf_fprint(file,ref->methodref->classref->name); fputc('\n',file);
2070 fprintf(file," name : ");
2071 utf_fprint(file,ref->methodref->name); fputc('\n',file);
2072 fprintf(file," descriptor: ");
2073 utf_fprint(file,ref->methodref->descriptor); fputc('\n',file);
2074 fprintf(file," parseddesc: ");
2075 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2076 fprintf(file," flags : %04x\n",ref->flags);
2077 fprintf(file," instancetypes:\n");
2078 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2079 fprintf(file," paramconstraints:\n");
2080 if (ref->paramconstraints) {
2081 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2082 fprintf(file," param %d:\n",i);
2083 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2087 fprintf(file," (empty)\n");
2094 * These are local overrides for various environment variables in Emacs.
2095 * Please do not remove this and leave it at the end of the file, where
2096 * Emacs will automagically detect them.
2097 * ---------------------------------------------------------------------
2100 * indent-tabs-mode: t
2104 * vim:noexpandtab:sw=4:ts=4: