1 /* src/vm/resolve.c - resolving classes/interfaces/fields/methods
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Edwin Steiner
29 Changes: Christan Thalinger
31 $Id: resolve.c 4857 2006-04-28 11:24:39Z edwin $
40 #include "mm/memory.h"
41 #include "vm/resolve.h"
42 #include "vm/access.h"
43 #include "vm/classcache.h"
44 #include "vm/descriptor.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/linker.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/stringlocal.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/verify/typeinfo.h"
55 /******************************************************************************/
57 /******************************************************************************/
59 /*#define RESOLVE_VERBOSE*/
61 /******************************************************************************/
62 /* CLASS RESOLUTION */
63 /******************************************************************************/
65 /* resolve_class_from_name *****************************************************
67 Resolve a symbolic class reference
70 referer..........the class containing the reference
71 refmethod........the method from which resolution was triggered
72 (may be NULL if not applicable)
73 classname........class name to resolve
74 mode.............mode of resolution:
75 resolveLazy...only resolve if it does not
76 require loading classes
77 resolveEager..load classes if necessary
78 checkaccess......if true, access rights to the class are checked
79 link.............if true, guarantee that the returned class, if any,
83 *result..........set to result of resolution, or to NULL if
84 the reference has not been resolved
85 In the case of an exception, *result is
86 guaranteed to be set to NULL.
89 true.............everything ok
90 (*result may still be NULL for resolveLazy)
91 false............an exception has been thrown
94 The returned class is *not* guaranteed to be linked!
95 (It is guaranteed to be loaded, though.)
97 *******************************************************************************/
99 bool resolve_class_from_name(classinfo *referer,
100 methodinfo *refmethod,
107 classinfo *cls = NULL;
114 assert(mode == resolveLazy || mode == resolveEager);
118 #ifdef RESOLVE_VERBOSE
119 fprintf(stderr,"resolve_class_from_name(");
120 utf_fprint(stderr,referer->name);
121 fprintf(stderr,",%p,",referer->classloader);
122 utf_fprint(stderr,classname);
123 fprintf(stderr,",%d,%d)\n",(int)checkaccess,(int)link);
126 /* lookup if this class has already been loaded */
128 cls = classcache_lookup(referer->classloader, classname);
130 #ifdef RESOLVE_VERBOSE
131 fprintf(stderr," lookup result: %p\n",(void*)cls);
135 /* resolve array types */
137 if (classname->text[0] == '[') {
138 utf_ptr = classname->text + 1;
139 len = classname->blength - 1;
141 /* classname is an array type name */
149 /* the component type is a reference type */
150 /* resolve the component type */
151 if (!resolve_class_from_name(referer,refmethod,
152 utf_new(utf_ptr,len),
153 mode,checkaccess,link,&cls))
154 return false; /* exception */
156 assert(mode == resolveLazy);
157 return true; /* be lazy */
159 /* create the array class */
160 cls = class_array_of(cls,false);
162 return false; /* exception */
166 /* the class has not been loaded, yet */
167 if (mode == resolveLazy)
168 return true; /* be lazy */
171 #ifdef RESOLVE_VERBOSE
172 fprintf(stderr," loading...\n");
177 if (!(cls = load_class_from_classloader(classname,
178 referer->classloader)))
179 return false; /* exception */
183 /* the class is now loaded */
185 assert(cls->state & CLASS_LOADED);
187 #ifdef RESOLVE_VERBOSE
188 fprintf(stderr," checking access rights...\n");
191 /* check access rights of referer to refered class */
192 if (checkaccess && !access_is_accessible_class(referer,cls)) {
196 msglen = utf_strlen(cls->name) + utf_strlen(referer->name) + 100;
197 message = MNEW(char,msglen);
198 strcpy(message,"class is not accessible (");
199 utf_sprint_classname(message+strlen(message),cls->name);
200 strcat(message," from ");
201 utf_sprint_classname(message+strlen(message),referer->name);
203 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
204 MFREE(message,char,msglen);
205 return false; /* exception */
208 /* link the class if necessary */
210 if (!(cls->state & CLASS_LINKED))
211 if (!link_class(cls))
212 return false; /* exception */
214 assert(cls->state & CLASS_LINKED);
217 /* resolution succeeds */
218 #ifdef RESOLVE_VERBOSE
219 fprintf(stderr," success.\n");
225 /* resolve_classref ************************************************************
227 Resolve a symbolic class reference
230 refmethod........the method from which resolution was triggered
231 (may be NULL if not applicable)
232 ref..............class reference
233 mode.............mode of resolution:
234 resolveLazy...only resolve if it does not
235 require loading classes
236 resolveEager..load classes if necessary
237 checkaccess......if true, access rights to the class are checked
238 link.............if true, guarantee that the returned class, if any,
242 *result..........set to result of resolution, or to NULL if
243 the reference has not been resolved
244 In the case of an exception, *result is
245 guaranteed to be set to NULL.
248 true.............everything ok
249 (*result may still be NULL for resolveLazy)
250 false............an exception has been thrown
252 *******************************************************************************/
254 bool resolve_classref(methodinfo *refmethod,
255 constant_classref *ref,
261 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
264 /* resolve_classref_or_classinfo ***********************************************
266 Resolve a symbolic class reference if necessary
269 refmethod........the method from which resolution was triggered
270 (may be NULL if not applicable)
271 cls..............class reference or classinfo
272 mode.............mode of resolution:
273 resolveLazy...only resolve if it does not
274 require loading classes
275 resolveEager..load classes if necessary
276 checkaccess......if true, access rights to the class are checked
277 link.............if true, guarantee that the returned class, if any,
281 *result..........set to result of resolution, or to NULL if
282 the reference has not been resolved
283 In the case of an exception, *result is
284 guaranteed to be set to NULL.
287 true.............everything ok
288 (*result may still be NULL for resolveLazy)
289 false............an exception has been thrown
291 *******************************************************************************/
293 bool resolve_classref_or_classinfo(methodinfo *refmethod,
294 classref_or_classinfo cls,
303 assert(mode == resolveEager || mode == resolveLazy);
306 #ifdef RESOLVE_VERBOSE
307 fprintf(stderr,"resolve_classref_or_classinfo(");
308 utf_fprint(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
309 fprintf(stderr,",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
314 if (IS_CLASSREF(cls)) {
315 /* we must resolve this reference */
317 if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
318 mode, checkaccess, link, &c))
319 goto return_exception;
322 /* cls has already been resolved */
324 assert(c->state & CLASS_LOADED);
326 assert(c || (mode == resolveLazy));
329 return true; /* be lazy */
332 assert(c->state & CLASS_LOADED);
335 if (!(c->state & CLASS_LINKED))
337 goto return_exception;
339 assert(c->state & CLASS_LINKED);
352 /* resolve_class_from_typedesc *************************************************
354 Return a classinfo * for the given type descriptor
357 d................type descriptor
358 checkaccess......if true, access rights to the class are checked
359 link.............if true, guarantee that the returned class, if any,
362 *result..........set to result of resolution, or to NULL if
363 the reference has not been resolved
364 In the case of an exception, *result is
365 guaranteed to be set to NULL.
368 true.............everything ok
369 false............an exception has been thrown
372 This function always resolved eagerly.
374 *******************************************************************************/
376 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
385 #ifdef RESOLVE_VERBOSE
386 fprintf(stderr,"resolve_class_from_typedesc(");
387 descriptor_debug_print_typedesc(stderr,d);
388 fprintf(stderr,",%i,%i)\n",(int)checkaccess,(int)link);
391 if (d->type == TYPE_ADR) {
392 /* a reference type */
394 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
395 resolveEager,checkaccess,link,&cls))
396 return false; /* exception */
399 /* a primitive type */
400 cls = primitivetype_table[d->decltype].class_primitive;
401 assert(cls->state & CLASS_LOADED);
402 if (!(cls->state & CLASS_LINKED))
403 if (!link_class(cls))
404 return false; /* exception */
407 assert(cls->state & CLASS_LOADED);
408 assert(!link || (cls->state & CLASS_LINKED));
410 #ifdef RESOLVE_VERBOSE
411 fprintf(stderr," result = ");utf_fprint(stderr,cls->name);fprintf(stderr,"\n");
418 /******************************************************************************/
419 /* SUBTYPE SET CHECKS */
420 /******************************************************************************/
422 /* resolve_subtype_check *******************************************************
424 Resolve the given types lazily and perform a subtype check
427 refmethod........the method triggering the resolution
428 subtype..........checked to be a subtype of supertype
429 supertype........the super type to check agaings
430 mode.............mode of resolution:
431 resolveLazy...only resolve if it does not
432 require loading classes
433 resolveEager..load classes if necessary
434 error............which type of exception to throw if
435 the test fails. May be:
436 resolveLinkageError, or
437 resolveIllegalAccessError
438 IMPORTANT: If error==resolveIllegalAccessError,
439 then array types are not checked.
442 resolveSucceeded.....the check succeeded
443 resolveDeferred......the check could not be performed due to
444 unresolved types. (This can only happen for
445 mode == resolveLazy.)
446 resolveFailed........the check failed, an exception has been thrown.
449 The types are resolved first, so any
450 exception which may occurr during resolution may
451 be thrown by this function.
453 *******************************************************************************/
455 #if defined(ENABLE_VERIFIER)
456 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
457 classref_or_classinfo subtype,
458 classref_or_classinfo supertype,
468 assert(supertype.any);
469 assert(mode == resolveLazy || mode == resolveEager);
470 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
472 /* resolve the subtype */
474 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
475 /* the subclass could not be resolved. therefore we are sure that */
476 /* no instances of this subclass will ever exist -> skip this test */
477 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
478 *exceptionptr = NULL;
479 return resolveSucceeded;
482 return resolveDeferred; /* be lazy */
484 assert(subclass->state & CLASS_LINKED);
486 /* do not check access to protected members of arrays */
488 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
489 return resolveSucceeded;
492 /* perform the subtype check */
494 typeinfo_init_classinfo(&subti,subclass);
496 r = typeinfo_is_assignable_to_class(&subti,supertype);
497 if (r == typecheck_FAIL)
498 return resolveFailed; /* failed, exception is already set */
500 if (r == typecheck_MAYBE) {
501 assert(IS_CLASSREF(supertype));
502 if (mode == resolveEager) {
503 if (!resolve_classref_or_classinfo(refmethod,supertype,
504 resolveEager,false,true,
507 return resolveFailed;
509 assert(supertype.cls);
513 return resolveDeferred; /* be lazy */
517 /* sub class relationship is false */
522 msglen = utf_strlen(subclass->name) + utf_strlen(CLASSREF_OR_CLASSINFO_NAME(supertype)) + 200;
523 message = MNEW(char,msglen);
524 strcpy(message,(error == resolveIllegalAccessError) ?
525 "illegal access to protected member ("
526 : "subtype constraint violated (");
527 utf_sprint_classname(message+strlen(message),subclass->name);
528 strcat(message," is not a subclass of ");
529 utf_sprint_classname(message+strlen(message),CLASSREF_OR_CLASSINFO_NAME(supertype));
531 if (error == resolveIllegalAccessError)
532 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
534 *exceptionptr = exceptions_new_linkageerror(message,NULL);
535 MFREE(message,char,msglen);
536 return resolveFailed; /* exception */
541 return resolveSucceeded;
543 #endif /* defined(ENABLE_VERIFIER) */
545 /* resolve_lazy_subtype_checks *************************************************
547 Resolve the types to check lazily and perform subtype checks
550 refmethod........the method triggering the resolution
551 subtinfo.........the typeinfo containing the subtypes
552 supertype........the supertype to test againgst
553 mode.............mode of resolution:
554 resolveLazy...only resolve if it does not
555 require loading classes
556 resolveEager..load classes if necessary
557 error............which type of exception to throw if
558 the test fails. May be:
559 resolveLinkageError, or
560 resolveIllegalAccessError
561 IMPORTANT: If error==resolveIllegalAccessError,
562 then array types in the set are skipped.
565 resolveSucceeded.....the check succeeded
566 resolveDeferred......the check could not be performed due to
568 resolveFailed........the check failed, an exception has been thrown.
571 The references in the set are resolved first, so any
572 exception which may occurr during resolution may
573 be thrown by this function.
575 *******************************************************************************/
577 #if defined(ENABLE_VERIFIER)
578 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
580 classref_or_classinfo supertype,
585 resolve_result_t result;
589 assert(supertype.any);
590 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
592 /* returnAddresses are illegal here */
594 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
595 *exceptionptr = new_verifyerror(refmethod,
596 "Invalid use of returnAddress");
597 return resolveFailed;
600 /* uninitialized objects are illegal here */
602 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
603 *exceptionptr = new_verifyerror(refmethod,
604 "Invalid use of uninitialized object");
605 return resolveFailed;
608 /* the nulltype is always assignable */
610 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
611 return resolveSucceeded;
613 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
615 if (supertype.cls == class_java_lang_Object
616 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
617 && refmethod->class->classloader == NULL))
619 return resolveSucceeded;
622 if (subtinfo->merged) {
624 /* for a merged type we have to do a series of checks */
626 count = subtinfo->merged->count;
627 for (i=0; i<count; ++i) {
628 classref_or_classinfo c = subtinfo->merged->list[i];
629 if (subtinfo->dimension > 0) {
630 /* a merge of array types */
631 /* the merged list contains the possible _element_ types, */
632 /* so we have to create array types with these elements. */
633 if (IS_CLASSREF(c)) {
634 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
637 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
641 /* do the subtype check against the type c */
643 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
644 if (result != resolveSucceeded)
650 /* a single type, this is the common case, hopefully */
652 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
653 == CLASSREF_OR_CLASSINFO_NAME(supertype))
655 /* the class names are the same */
656 /* equality is guaranteed by the loading constraints */
657 return resolveSucceeded;
661 /* some other type name, try to perform the check lazily */
663 return resolve_subtype_check(refmethod,
664 subtinfo->typeclass,supertype,
671 return resolveSucceeded;
673 #endif /* defined(ENABLE_VERIFIER) */
675 /* resolve_and_check_subtype_set ***********************************************
677 Resolve the references in the given set and test subtype relationships
680 refmethod........the method triggering the resolution
681 ref..............a set of class/interface references
683 typeref..........the type to test against the set
684 mode.............mode of resolution:
685 resolveLazy...only resolve if it does not
686 require loading classes
687 resolveEager..load classes if necessary
688 error............which type of exception to throw if
689 the test fails. May be:
690 resolveLinkageError, or
691 resolveIllegalAccessError
692 IMPORTANT: If error==resolveIllegalAccessError,
693 then array types in the set are skipped.
696 resolveSucceeded.....the check succeeded
697 resolveDeferred......the check could not be performed due to
698 unresolved types. (This can only happen if
699 mode == resolveLazy.)
700 resolveFailed........the check failed, an exception has been thrown.
703 The references in the set are resolved first, so any
704 exception which may occurr during resolution may
705 be thrown by this function.
707 *******************************************************************************/
709 #if defined(ENABLE_VERIFIER)
710 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
711 unresolved_subtype_set *ref,
712 classref_or_classinfo typeref,
716 classref_or_classinfo *setp;
717 typecheck_result checkresult;
722 assert(mode == resolveLazy || mode == resolveEager);
723 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
725 setp = ref->subtyperefs;
727 /* an empty set of tests always succeeds */
728 if (!setp || !setp->any) {
729 return resolveSucceeded;
732 /* first resolve the type if necessary */
733 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
734 return resolveFailed; /* exception */
736 return resolveDeferred; /* be lazy */
738 assert(typeref.cls->state & CLASS_LINKED);
740 /* iterate over the set members */
742 for (; setp->any; ++setp) {
743 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
744 if (checkresult != resolveSucceeded)
749 return resolveSucceeded;
751 #endif /* defined(ENABLE_VERIFIER) */
753 /******************************************************************************/
754 /* CLASS RESOLUTION */
755 /******************************************************************************/
757 /* resolve_class ***************************************************************
759 Resolve an unresolved class reference. The class is also linked.
762 ref..............struct containing the reference
763 mode.............mode of resolution:
764 resolveLazy...only resolve if it does not
765 require loading classes
766 resolveEager..load classes if necessary
767 checkaccess......if true, access rights to the class are checked
770 *result..........set to the result of resolution, or to NULL if
771 the reference has not been resolved
772 In the case of an exception, *result is
773 guaranteed to be set to NULL.
776 true.............everything ok
777 (*result may still be NULL for resolveLazy)
778 false............an exception has been thrown
780 *******************************************************************************/
782 #ifdef ENABLE_VERIFIER
783 bool resolve_class(unresolved_class *ref,
789 resolve_result_t checkresult;
793 assert(mode == resolveLazy || mode == resolveEager);
797 #ifdef RESOLVE_VERBOSE
798 unresolved_class_debug_dump(ref,stderr);
801 /* first we must resolve the class */
802 if (!resolve_classref(ref->referermethod,
803 ref->classref,mode,checkaccess,true,&cls))
805 /* the class reference could not be resolved */
806 return false; /* exception */
809 return true; /* be lazy */
812 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
814 /* now we check the subtype constraints */
816 checkresult = resolve_and_check_subtype_set(ref->referermethod,
817 &(ref->subtypeconstraints),
818 CLASSREF_OR_CLASSINFO(cls),
820 resolveLinkageError);
821 if (checkresult != resolveSucceeded)
822 return (bool) checkresult;
828 #endif /* ENABLE_VERIFIER */
830 /* resolve_classref_eager ******************************************************
832 Resolve an unresolved class reference eagerly. The class is also linked and
833 access rights to the class are checked.
836 ref..............constant_classref to the class
839 classinfo * to the class, or
840 NULL if an exception has been thrown
842 *******************************************************************************/
844 classinfo * resolve_classref_eager(constant_classref *ref)
848 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
854 /* resolve_classref_eager_nonabstract ******************************************
856 Resolve an unresolved class reference eagerly. The class is also linked and
857 access rights to the class are checked. A check is performed that the class
861 ref..............constant_classref to the class
864 classinfo * to the class, or
865 NULL if an exception has been thrown
867 *******************************************************************************/
869 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
873 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
876 /* ensure that the class is not abstract */
878 if (c->flags & ACC_ABSTRACT) {
879 *exceptionptr = new_verifyerror(NULL,"creating instance of abstract class");
886 /* resolve_class_eager *********************************************************
888 Resolve an unresolved class reference eagerly. The class is also linked and
889 access rights to the class are checked.
892 ref..............struct containing the reference
895 classinfo * to the class, or
896 NULL if an exception has been thrown
898 *******************************************************************************/
900 #ifdef ENABLE_VERIFIER
901 classinfo * resolve_class_eager(unresolved_class *ref)
905 if (!resolve_class(ref,resolveEager,true,&c))
910 #endif /* ENABLE_VERIFIER */
912 /******************************************************************************/
913 /* FIELD RESOLUTION */
914 /******************************************************************************/
916 /* resolve_field_verifier_checks ***********************************************
918 Do the verifier checks necessary after field has been resolved.
921 refmethod........the method containing the reference
922 fieldref.........the field reference
923 container........the class where the field was found
924 fi...............the fieldinfo of the resolved field
925 opc..............opcode of the {GET,PUT}{STATIC,FIELD} instruction
928 resolveSucceeded....everything ok
929 resolveDeferred.....tests could not be done, have been deferred
930 resolveFailed.......exception has been thrown
932 *******************************************************************************/
934 #if defined(ENABLE_VERIFIER)
935 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
936 constant_FMIref *fieldref,
937 classinfo *container,
944 resolve_result_t result;
945 bool isstatic = false;
947 stackelement *instanceslot = NULL;
948 stackelement *valueslot = NULL;
949 constant_classref *fieldtyperef;
956 /* get the classinfos and the field type */
958 referer = refmethod->class;
961 declarer = fi->class;
963 assert(referer->state & CLASS_LINKED);
965 fieldtyperef = fieldref->parseddesc.fd->classref;
967 /* get opcode dependent values */
973 valueslot = curstack;
974 instanceslot = curstack->prev;
978 case ICMD_PUTFIELDCONST:
980 instanceslot = curstack;
986 valueslot = curstack;
989 case ICMD_PUTSTATICCONST:
995 instanceslot = curstack;
1006 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1009 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1010 /* a static field is accessed via an instance, or vice versa */
1012 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1013 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
1014 : "instance field accessed without instance");
1015 return resolveFailed;
1018 /* check access rights */
1020 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1024 msglen = utf_strlen(declarer->name) + utf_strlen(fi->name) + utf_strlen(referer->name) + 100;
1025 message = MNEW(char,msglen);
1026 strcpy(message,"field is not accessible (");
1027 utf_sprint_classname(message+strlen(message),declarer->name);
1028 strcat(message,".");
1029 utf_sprint(message+strlen(message),fi->name);
1030 strcat(message," from ");
1031 utf_sprint_classname(message+strlen(message),referer->name);
1032 strcat(message,")");
1033 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
1034 MFREE(message,char,msglen);
1035 return resolveFailed; /* exception */
1038 /* for non-static methods we have to check the constraints on the */
1045 /* The instanceslot must contain a reference to a non-array type */
1047 assert(instanceslot->type == TYPE_ADR); /* checked earlier */
1049 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
1050 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1051 return resolveFailed;
1053 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
1054 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on array");
1055 return resolveFailed;
1058 if (isput && TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1060 /* The instruction writes a field in an uninitialized object. */
1061 /* This is only allowed when a field of an uninitialized 'this' object is */
1062 /* written inside an initialization method */
1064 classinfo *initclass;
1065 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1068 *exceptionptr = new_verifyerror(refmethod,"accessing field of uninitialized object");
1069 return resolveFailed;
1072 /* XXX check that class of field == refmethod->class */
1073 initclass = referer; /* XXX classrefs */
1074 assert(initclass->state & CLASS_LINKED);
1076 typeinfo_init_classinfo(&tinfo,initclass);
1080 insttip = &(instanceslot->typeinfo);
1083 result = resolve_lazy_subtype_checks(refmethod,
1085 CLASSREF_OR_CLASSINFO(container),
1086 resolveLinkageError);
1087 if (result != resolveSucceeded)
1090 /* check protected access */
1092 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1094 result = resolve_lazy_subtype_checks(refmethod,
1095 &(instanceslot->typeinfo),
1096 CLASSREF_OR_CLASSINFO(referer),
1097 resolveIllegalAccessError);
1098 if (result != resolveSucceeded)
1104 /* for PUT* instructions we have to check the constraints on the value type */
1106 if (valueslot && valueslot->type == TYPE_ADR) {
1107 assert(fieldtyperef);
1109 /* check subtype constraints */
1110 result = resolve_lazy_subtype_checks(refmethod,
1111 &(valueslot->typeinfo),
1112 CLASSREF_OR_CLASSINFO(fieldtyperef),
1113 resolveLinkageError);
1115 if (result != resolveSucceeded)
1119 /* impose loading constraint on field type */
1121 if (fi->type == TYPE_ADR) {
1122 assert(fieldtyperef);
1123 if (!classcache_add_constraint(declarer->classloader,
1124 referer->classloader,
1125 fieldtyperef->name))
1126 return resolveFailed;
1129 /* XXX impose loading constraing on instance? */
1132 return resolveSucceeded;
1134 #endif /* defined(ENABLE_VERIFIER) */
1136 /* resolve_field_lazy **********************************************************
1138 Resolve an unresolved field reference lazily
1141 iptr.............instruction containing the field reference
1142 curstack.........instack of the instruction
1143 refmethod........the referer method
1146 resolveSucceeded.....the reference has been resolved
1147 resolveDeferred......the resolving could not be performed lazily
1148 resolveFailed........resolving failed, an exception has been thrown.
1150 *******************************************************************************/
1152 resolve_result_t resolve_field_lazy(instruction *iptr,stackptr curstack,
1153 methodinfo *refmethod)
1156 classinfo *container;
1158 constant_FMIref *fieldref;
1159 resolve_result_t result;
1164 /* the class containing the reference */
1166 referer = refmethod->class;
1169 /* get the field reference */
1171 if (iptr->opc == ICMD_PUTFIELDCONST || iptr->opc == ICMD_PUTSTATICCONST)
1172 INSTRUCTION_GET_FIELDREF(iptr + 1,fieldref);
1174 INSTRUCTION_GET_FIELDREF(iptr,fieldref);
1176 /* check if the field itself is already resolved */
1178 if (IS_FMIREF_RESOLVED(fieldref)) {
1179 fi = fieldref->p.field;
1180 container = fi->class;
1181 goto resolved_the_field;
1184 /* first we must resolve the class containg the field */
1186 /* XXX can/may lazyResolving trigger linking? */
1188 if (!resolve_class_from_name(referer,refmethod,
1189 fieldref->p.classref->name,resolveLazy,true,true,&container))
1191 /* the class reference could not be resolved */
1192 return resolveFailed; /* exception */
1195 return resolveDeferred; /* be lazy */
1197 assert(container->state & CLASS_LINKED);
1199 /* now we must find the declaration of the field in `container`
1200 * or one of its superclasses */
1202 fi = class_resolvefield(container,
1203 fieldref->name,fieldref->descriptor,
1206 /* The field does not exist. But since we were called lazily, */
1207 /* this error must not be reported now. (It will be reported */
1208 /* if eager resolving of this field is ever tried.) */
1210 *exceptionptr = NULL;
1211 return resolveDeferred; /* be lazy */
1214 /* cache the result of the resolution */
1216 fieldref->p.field = fi;
1220 #if defined(ENABLE_VERIFIER)
1222 result = resolve_field_verifier_checks(refmethod,fieldref,container,
1227 if (result != resolveSucceeded)
1230 #endif /* defined(ENABLE_VERIFIER) */
1233 return resolveSucceeded;
1236 /* resolve_field ***************************************************************
1238 Resolve an unresolved field reference
1241 ref..............struct containing the reference
1242 mode.............mode of resolution:
1243 resolveLazy...only resolve if it does not
1244 require loading classes
1245 resolveEager..load classes if necessary
1248 *result..........set to the result of resolution, or to NULL if
1249 the reference has not been resolved
1250 In the case of an exception, *result is
1251 guaranteed to be set to NULL.
1254 true.............everything ok
1255 (*result may still be NULL for resolveLazy)
1256 false............an exception has been thrown
1258 *******************************************************************************/
1260 bool resolve_field(unresolved_field *ref,
1261 resolve_mode_t mode,
1265 classinfo *container;
1266 classinfo *declarer;
1267 constant_classref *fieldtyperef;
1269 resolve_result_t checkresult;
1273 assert(mode == resolveLazy || mode == resolveEager);
1277 #ifdef RESOLVE_VERBOSE
1278 unresolved_field_debug_dump(ref,stderr);
1281 /* the class containing the reference */
1283 referer = ref->referermethod->class;
1286 /* check if the field itself is already resolved */
1287 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1288 fi = ref->fieldref->p.field;
1289 container = fi->class;
1290 goto resolved_the_field;
1293 /* first we must resolve the class containg the field */
1294 if (!resolve_class_from_name(referer,ref->referermethod,
1295 ref->fieldref->p.classref->name,mode,true,true,&container))
1297 /* the class reference could not be resolved */
1298 return false; /* exception */
1301 return true; /* be lazy */
1304 assert(container->state & CLASS_LOADED);
1305 assert(container->state & CLASS_LINKED);
1307 /* now we must find the declaration of the field in `container`
1308 * or one of its superclasses */
1310 #ifdef RESOLVE_VERBOSE
1311 fprintf(stderr," resolving field in class...\n");
1314 fi = class_resolvefield(container,
1315 ref->fieldref->name,ref->fieldref->descriptor,
1318 if (mode == resolveLazy) {
1319 /* The field does not exist. But since we were called lazily, */
1320 /* this error must not be reported now. (It will be reported */
1321 /* if eager resolving of this field is ever tried.) */
1323 *exceptionptr = NULL;
1324 return true; /* be lazy */
1327 return false; /* exception */
1330 /* cache the result of the resolution */
1331 ref->fieldref->p.field = fi;
1335 #ifdef ENABLE_VERIFIER
1337 checkresult = resolve_field_verifier_checks(ref->referermethod,
1341 /* XXX pass NULL instruction * */
1342 (ref->flags & RESOLVE_STATIC) ? ICMD_GETSTATIC : ICMD_GETFIELD,
1345 if (checkresult != resolveSucceeded)
1346 return (bool) checkresult;
1348 declarer = fi->class;
1350 assert(declarer->state & CLASS_LOADED);
1351 assert(declarer->state & CLASS_LINKED);
1353 /* for non-static accesses we have to check the constraints on the */
1356 if (!(ref->flags & RESOLVE_STATIC)) {
1357 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1358 &(ref->instancetypes),
1359 CLASSREF_OR_CLASSINFO(container),
1360 mode, resolveLinkageError);
1361 if (checkresult != resolveSucceeded)
1362 return (bool) checkresult;
1365 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1367 /* for PUT* instructions we have to check the constraints on the value type */
1368 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1369 assert(fieldtyperef);
1370 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1371 /* check subtype constraints */
1372 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1373 &(ref->valueconstraints),
1374 CLASSREF_OR_CLASSINFO(fieldtyperef),
1375 mode, resolveLinkageError);
1376 if (checkresult != resolveSucceeded)
1377 return (bool) checkresult;
1381 /* check protected access */
1382 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1383 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1384 &(ref->instancetypes),
1385 CLASSREF_OR_CLASSINFO(referer),
1387 resolveIllegalAccessError);
1388 if (checkresult != resolveSucceeded)
1389 return (bool) checkresult;
1393 #endif /* ENABLE_VERIFIER */
1401 /* resolve_field_eager *********************************************************
1403 Resolve an unresolved field reference eagerly.
1406 ref..............struct containing the reference
1409 fieldinfo * to the field, or
1410 NULL if an exception has been thrown
1412 *******************************************************************************/
1414 fieldinfo * resolve_field_eager(unresolved_field *ref)
1418 if (!resolve_field(ref,resolveEager,&fi))
1424 /******************************************************************************/
1425 /* METHOD RESOLUTION */
1426 /******************************************************************************/
1428 /* resolve_method_invokespecial_lookup *****************************************
1430 Do the special lookup for methods invoked by INVOKESPECIAL
1433 refmethod........the method containing the reference
1434 mi...............the methodinfo of the resolved method
1437 a methodinfo *...the result of the lookup,
1438 NULL.............an exception has been thrown
1440 *******************************************************************************/
1442 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1445 classinfo *declarer;
1451 /* get referer and declarer classes */
1453 referer = refmethod->class;
1456 declarer = mi->class;
1458 assert(referer->state & CLASS_LINKED);
1460 /* checks for INVOKESPECIAL: */
1461 /* for <init> and methods of the current class we don't need any */
1462 /* special checks. Otherwise we must verify that the called method */
1463 /* belongs to a super class of the current class */
1465 if ((referer != declarer) && (mi->name != utf_init)) {
1466 /* check that declarer is a super class of the current class */
1468 if (!class_issubclass(referer,declarer)) {
1469 *exceptionptr = new_verifyerror(refmethod,
1470 "INVOKESPECIAL calling non-super class method");
1474 /* if the referer has ACC_SUPER set, we must do the special */
1475 /* lookup starting with the direct super class of referer */
1477 if ((referer->flags & ACC_SUPER) != 0) {
1478 mi = class_resolvemethod(referer->super.cls,
1482 /* the spec calls for an AbstractMethodError in this case */
1483 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
1493 /* resolve_method_verifier_checks **********************************************
1495 Do the verifier checks necessary after a method has been resolved.
1498 refmethod........the method containing the reference
1499 methodref........the method reference
1500 container........the class where the method was found
1501 mi...............the methodinfo of the resolved method
1502 invokestatic.....true if the method is invoked by INVOKESTATIC
1505 resolveSucceeded....everything ok
1506 resolveDeferred.....tests could not be done, have been deferred
1507 resolveFailed.......exception has been thrown
1509 *******************************************************************************/
1511 #if defined(ENABLE_VERIFIER)
1512 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1513 constant_FMIref *methodref,
1514 classinfo *container,
1520 classinfo *declarer;
1522 resolve_result_t result;
1524 typedesc *paramtypes;
1526 stackelement *instanceslot = NULL;
1527 stackelement *param;
1537 #ifdef RESOLVE_VERBOSE
1538 fprintf(stderr,"resolve_method_verifier_checks\n");
1539 fprintf(stderr," flags: %02x\n",mi->flags);
1542 /* get the classinfos and the method descriptor */
1544 referer = refmethod->class;
1547 declarer = mi->class;
1549 assert(referer->state & CLASS_LINKED);
1551 md = methodref->parseddesc.md;
1555 instancecount = (invokestatic) ? 0 : 1;
1559 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1560 /* a static method is accessed via an instance, or vice versa */
1562 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1563 (mi->flags & ACC_STATIC) ? "static method called via instance"
1564 : "instance method called without instance");
1565 return resolveFailed;
1568 /* check access rights */
1570 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1574 /* XXX clean this up. this should be in exceptions.c */
1575 msglen = utf_strlen(declarer->name) + utf_strlen(mi->name) +
1576 utf_strlen(mi->descriptor) + utf_strlen(referer->name) + 100;
1577 message = MNEW(char,msglen);
1578 strcpy(message,"method is not accessible (");
1579 utf_sprint_classname(message+strlen(message),declarer->name);
1580 strcat(message,".");
1581 utf_sprint(message+strlen(message),mi->name);
1582 utf_sprint(message+strlen(message),mi->descriptor);
1583 strcat(message," from ");
1584 utf_sprint_classname(message+strlen(message),referer->name);
1585 strcat(message,")");
1586 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
1587 MFREE(message,char,msglen);
1588 return resolveFailed; /* exception */
1592 /* for non-static methods we have to check the constraints on the */
1595 if (!invokestatic) {
1596 /* find the instance slot under all the parameter slots on the stack */
1597 instanceslot = curstack;
1598 for (i=1; i<md->paramcount; ++i)
1599 instanceslot = instanceslot->prev;
1602 assert((instanceslot && instancecount == 1) || invokestatic);
1604 /* record subtype constraints for the instance type, if any */
1608 assert(instanceslot->type == TYPE_ADR);
1610 if (invokespecial &&
1611 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1612 { /* XXX clean up */
1613 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1614 classref_or_classinfo initclass = (ins) ? CLASSREF_OR_CLASSINFO(ins[-1].target)
1615 : CLASSREF_OR_CLASSINFO(refmethod->class);
1617 if (!typeinfo_init_class(tip,initclass))
1621 tip = &(instanceslot->typeinfo);
1624 result = resolve_lazy_subtype_checks(refmethod,
1626 CLASSREF_OR_CLASSINFO(container),
1627 resolveLinkageError);
1628 if (result != resolveSucceeded)
1631 /* check protected access */
1633 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1635 result = resolve_lazy_subtype_checks(refmethod,
1637 CLASSREF_OR_CLASSINFO(referer),
1638 resolveIllegalAccessError);
1639 if (result != resolveSucceeded)
1645 /* check subtype constraints for TYPE_ADR parameters */
1647 assert(md->paramcount == methodref->parseddesc.md->paramcount);
1648 paramtypes = md->paramtypes;
1651 for (i = md->paramcount-1-instancecount; i>=0; --i, param = param->prev) {
1652 type = md->paramtypes[i+instancecount].type;
1655 assert(type == param->type);
1657 if (type == TYPE_ADR) {
1658 result = resolve_lazy_subtype_checks(refmethod,
1660 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1661 resolveLinkageError);
1662 if (result != resolveSucceeded)
1667 } /* if (curstack) */
1669 /* impose loading constraints on parameters (including instance) */
1671 paramtypes = md->paramtypes;
1673 for (i = 0; i < md->paramcount; i++) {
1674 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1677 if (i < instancecount) {
1678 /* The type of the 'this' pointer is the class containing */
1679 /* the method definition. Since container is the same as, */
1680 /* or a subclass of declarer, we also constrain declarer */
1681 /* by transitivity of loading constraints. */
1682 name = container->name;
1685 name = paramtypes[i].classref->name;
1688 /* The caller (referer) and the callee (container) must agree */
1689 /* on the types of the parameters. */
1690 if (!classcache_add_constraint(referer->classloader,
1691 container->classloader, name))
1692 return resolveFailed; /* exception */
1696 /* impose loading constraint onto return type */
1698 if (md->returntype.type == TYPE_ADR) {
1699 /* The caller (referer) and the callee (container) must agree */
1700 /* on the return type. */
1701 if (!classcache_add_constraint(referer->classloader,container->classloader,
1702 md->returntype.classref->name))
1703 return resolveFailed; /* exception */
1707 return resolveSucceeded;
1709 #endif /* defined(ENABLE_VERIFIER) */
1711 /* resolve_method_lazy *********************************************************
1713 Resolve an unresolved method reference lazily
1716 iptr.............instruction containing the method reference
1717 curstack.........instack of the instruction
1718 refmethod........the referer method
1721 resolveSucceeded.....the reference has been resolved
1722 resolveDeferred......the resolving could not be performed lazily
1723 resolveFailed........resolving failed, an exception has been thrown.
1725 *******************************************************************************/
1727 resolve_result_t resolve_method_lazy(instruction *iptr,stackptr curstack,
1728 methodinfo *refmethod)
1731 classinfo *container;
1733 constant_FMIref *methodref;
1734 resolve_result_t result;
1739 #ifdef RESOLVE_VERBOSE
1740 fprintf(stderr,"resolve_method_lazy\n");
1743 /* the class containing the reference */
1745 referer = refmethod->class;
1748 /* the method reference */
1750 INSTRUCTION_GET_METHODREF(iptr,methodref);
1752 /* check if the method itself is already resolved */
1754 if (IS_FMIREF_RESOLVED(methodref)) {
1755 mi = methodref->p.method;
1756 container = mi->class;
1757 goto resolved_the_method;
1760 /* first we must resolve the class containg the method */
1762 if (!resolve_class_from_name(referer,refmethod,
1763 methodref->p.classref->name,resolveLazy,true,true,&container))
1765 /* the class reference could not be resolved */
1766 return resolveFailed; /* exception */
1769 return resolveDeferred; /* be lazy */
1771 assert(container->state & CLASS_LINKED);
1773 /* now we must find the declaration of the method in `container`
1774 * or one of its superclasses */
1776 if (container->flags & ACC_INTERFACE) {
1777 mi = class_resolveinterfacemethod(container,
1779 methodref->descriptor,
1783 mi = class_resolveclassmethod(container,
1785 methodref->descriptor,
1790 /* The method does not exist. But since we were called lazily, */
1791 /* this error must not be reported now. (It will be reported */
1792 /* if eager resolving of this method is ever tried.) */
1794 *exceptionptr = NULL;
1795 return resolveDeferred; /* be lazy */
1798 if (iptr->opc == ICMD_INVOKESPECIAL) {
1799 mi = resolve_method_invokespecial_lookup(refmethod,mi);
1801 return resolveFailed; /* exception */
1804 /* have the method params already been parsed? no, do it. */
1806 if (!mi->parseddesc->params)
1807 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1808 return resolveFailed;
1810 /* cache the result of the resolution */
1812 methodref->p.method = mi;
1814 resolved_the_method:
1816 #if defined(ENABLE_VERIFIER)
1818 result = resolve_method_verifier_checks(refmethod,methodref,container,
1820 iptr->opc == ICMD_INVOKESTATIC,
1821 iptr->opc == ICMD_INVOKESPECIAL,
1823 if (result != resolveSucceeded)
1826 #endif /* defined(ENABLE_VERIFIER) */
1828 /* if this call is monomorphic, turn it into an INVOKESPECIAL */
1830 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1831 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1833 iptr->opc = ICMD_INVOKESPECIAL;
1837 return resolveSucceeded;
1840 /* resolve_method **************************************************************
1842 Resolve an unresolved method reference
1845 ref..............struct containing the reference
1846 mode.............mode of resolution:
1847 resolveLazy...only resolve if it does not
1848 require loading classes
1849 resolveEager..load classes if necessary
1852 *result..........set to the result of resolution, or to NULL if
1853 the reference has not been resolved
1854 In the case of an exception, *result is
1855 guaranteed to be set to NULL.
1858 true.............everything ok
1859 (*result may still be NULL for resolveLazy)
1860 false............an exception has been thrown
1862 *******************************************************************************/
1864 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1867 classinfo *container;
1868 classinfo *declarer;
1870 typedesc *paramtypes;
1873 resolve_result_t checkresult;
1877 assert(mode == resolveLazy || mode == resolveEager);
1879 #ifdef RESOLVE_VERBOSE
1880 unresolved_method_debug_dump(ref,stderr);
1885 /* the class containing the reference */
1887 referer = ref->referermethod->class;
1890 /* check if the method itself is already resolved */
1892 if (IS_FMIREF_RESOLVED(ref->methodref)) {
1893 mi = ref->methodref->p.method;
1894 container = mi->class;
1895 goto resolved_the_method;
1898 /* first we must resolve the class containing the method */
1900 if (!resolve_class_from_name(referer,ref->referermethod,
1901 ref->methodref->p.classref->name,mode,true,true,&container))
1903 /* the class reference could not be resolved */
1904 return false; /* exception */
1907 return true; /* be lazy */
1910 assert(container->state & CLASS_LINKED);
1912 /* now we must find the declaration of the method in `container`
1913 * or one of its superclasses */
1915 if (container->flags & ACC_INTERFACE) {
1916 mi = class_resolveinterfacemethod(container,
1917 ref->methodref->name,
1918 ref->methodref->descriptor,
1922 mi = class_resolveclassmethod(container,
1923 ref->methodref->name,
1924 ref->methodref->descriptor,
1929 if (mode == resolveLazy) {
1930 /* The method does not exist. But since we were called lazily, */
1931 /* this error must not be reported now. (It will be reported */
1932 /* if eager resolving of this method is ever tried.) */
1934 *exceptionptr = NULL;
1935 return true; /* be lazy */
1938 return false; /* exception */ /* XXX set exceptionptr? */
1941 /* { the method reference has been resolved } */
1943 if (ref->flags & RESOLVE_SPECIAL) {
1944 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
1946 return false; /* exception */
1949 /* have the method params already been parsed? no, do it. */
1951 if (!mi->parseddesc->params)
1952 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1955 /* cache the resolution */
1957 ref->methodref->p.method = mi;
1959 resolved_the_method:
1961 #ifdef ENABLE_VERIFIER
1964 checkresult = resolve_method_verifier_checks(ref->referermethod,
1968 (ref->flags & RESOLVE_STATIC),
1969 (ref->flags & RESOLVE_SPECIAL),
1972 if (checkresult != resolveSucceeded)
1973 return (bool) checkresult;
1975 declarer = mi->class;
1977 assert(referer->state & CLASS_LINKED);
1979 /* for non-static methods we have to check the constraints on the */
1982 if (!(ref->flags & RESOLVE_STATIC)) {
1983 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1984 &(ref->instancetypes),
1985 CLASSREF_OR_CLASSINFO(container),
1987 resolveLinkageError);
1988 if (checkresult != resolveSucceeded)
1989 return (bool) checkresult;
1996 /* check subtype constraints for TYPE_ADR parameters */
1998 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
1999 paramtypes = mi->parseddesc->paramtypes;
2001 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2002 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2003 if (ref->paramconstraints) {
2004 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2005 ref->paramconstraints + i,
2006 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2008 resolveLinkageError);
2009 if (checkresult != resolveSucceeded)
2010 return (bool) checkresult;
2015 /* check protected access */
2017 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2019 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2020 &(ref->instancetypes),
2021 CLASSREF_OR_CLASSINFO(referer),
2023 resolveIllegalAccessError);
2024 if (checkresult != resolveSucceeded)
2025 return (bool) checkresult;
2028 #endif /* ENABLE_VERIFIER */
2035 /* resolve_method_eager ********************************************************
2037 Resolve an unresolved method reference eagerly.
2040 ref..............struct containing the reference
2043 methodinfo * to the method, or
2044 NULL if an exception has been thrown
2046 *******************************************************************************/
2048 methodinfo * resolve_method_eager(unresolved_method *ref)
2052 if (!resolve_method(ref,resolveEager,&mi))
2058 /******************************************************************************/
2059 /* CREATING THE DATA STRUCTURES */
2060 /******************************************************************************/
2062 #ifdef ENABLE_VERIFIER
2063 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2064 methodinfo *refmethod,
2065 unresolved_subtype_set *stset,
2067 constant_classref *declaredtype)
2075 #ifdef RESOLVE_VERBOSE
2076 fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
2077 #ifdef TYPEINFO_DEBUG
2078 typeinfo_print(stderr,tinfo,4);
2080 fprintf(stderr," declared type:");utf_fprint(stderr,declaredtype->name);
2081 fprintf(stderr,"\n");
2084 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2085 *exceptionptr = new_verifyerror(refmethod,
2086 "Invalid use of returnAddress");
2090 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2091 *exceptionptr = new_verifyerror(refmethod,
2092 "Invalid use of uninitialized object");
2096 /* the nulltype is always assignable */
2097 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2100 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2101 if (declaredtype->name == utf_java_lang_Object
2102 && referer->classloader == NULL)
2107 if (tinfo->merged) {
2108 count = tinfo->merged->count;
2109 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2110 for (i=0; i<count; ++i) {
2111 classref_or_classinfo c = tinfo->merged->list[i];
2112 if (tinfo->dimension > 0) {
2113 /* a merge of array types */
2114 /* the merged list contains the possible _element_ types, */
2115 /* so we have to create array types with these elements. */
2116 if (IS_CLASSREF(c)) {
2117 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2120 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2123 stset->subtyperefs[i] = c;
2125 stset->subtyperefs[count].any = NULL; /* terminate */
2128 if ((IS_CLASSREF(tinfo->typeclass)
2129 ? tinfo->typeclass.ref->name
2130 : tinfo->typeclass.cls->name) == declaredtype->name)
2132 /* the class names are the same */
2133 /* equality is guaranteed by the loading constraints */
2137 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2138 stset->subtyperefs[0] = tinfo->typeclass;
2139 stset->subtyperefs[1].any = NULL; /* terminate */
2146 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2149 #endif /* ENABLE_VERIFIER */
2151 /* create_unresolved_class *****************************************************
2153 Create an unresolved_class struct for the given class reference
2156 refmethod........the method triggering the resolution (if any)
2157 classref.........the class reference
2158 valuetype........value type to check against the resolved class
2159 may be NULL, if no typeinfo is available
2162 a pointer to a new unresolved_class struct, or
2163 NULL if an exception has been thrown
2165 *******************************************************************************/
2167 #ifdef ENABLE_VERIFIER
2168 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2169 constant_classref *classref,
2170 typeinfo *valuetype)
2172 unresolved_class *ref;
2174 #ifdef RESOLVE_VERBOSE
2175 fprintf(stderr,"create_unresolved_class\n");
2176 fprintf(stderr," referer: ");utf_fprint(stderr,classref->referer->name);fputc('\n',stderr);
2178 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
2179 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
2181 fprintf(stderr," name : ");utf_fprint(stderr,classref->name);fputc('\n',stderr);
2184 ref = NEW(unresolved_class);
2185 ref->classref = classref;
2186 ref->referermethod = refmethod;
2189 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2190 &(ref->subtypeconstraints),valuetype,classref))
2194 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2199 #endif /* ENABLE_VERIFIER */
2201 /* create_unresolved_field *****************************************************
2203 Create an unresolved_field struct for the given field access instruction
2206 referer..........the class containing the reference
2207 refmethod........the method triggering the resolution (if any)
2208 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2211 a pointer to a new unresolved_field struct, or
2212 NULL if an exception has been thrown
2214 *******************************************************************************/
2216 unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refmethod,
2219 unresolved_field *ref;
2220 constant_FMIref *fieldref = NULL;
2222 #ifdef RESOLVE_VERBOSE
2223 fprintf(stderr,"create_unresolved_field\n");
2224 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
2225 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
2226 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
2229 ref = NEW(unresolved_field);
2231 ref->referermethod = refmethod;
2232 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2234 switch (iptr[0].opc) {
2236 ref->flags |= RESOLVE_PUTFIELD;
2237 fieldref = (constant_FMIref *) iptr[0].val.a;
2240 case ICMD_PUTFIELDCONST:
2241 ref->flags |= RESOLVE_PUTFIELD;
2242 fieldref = (constant_FMIref *) iptr[1].val.a;
2245 case ICMD_PUTSTATIC:
2246 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2247 fieldref = (constant_FMIref *) iptr[0].val.a;
2250 case ICMD_PUTSTATICCONST:
2251 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2252 fieldref = (constant_FMIref *) iptr[1].val.a;
2256 fieldref = (constant_FMIref *) iptr[0].val.a;
2259 case ICMD_GETSTATIC:
2260 ref->flags |= RESOLVE_STATIC;
2261 fieldref = (constant_FMIref *) iptr[0].val.a;
2267 #ifdef RESOLVE_VERBOSE
2268 fprintf(stderr," class : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
2269 fprintf(stderr," name : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
2270 fprintf(stderr," desc : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
2271 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
2273 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2276 ref->fieldref = fieldref;
2281 /* constrain_unresolved_field **************************************************
2283 Record subtype constraints for a field access.
2286 ref..............the unresolved_field structure of the access
2287 referer..........the class containing the reference
2288 refmethod........the method triggering the resolution (if any)
2289 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2290 stack............the input stack of the instruction
2293 true.............everything ok
2294 false............an exception has been thrown
2296 *******************************************************************************/
2298 #ifdef ENABLE_VERIFIER
2299 bool constrain_unresolved_field(unresolved_field *ref,
2300 classinfo *referer, methodinfo *refmethod,
2302 stackelement *stack)
2304 constant_FMIref *fieldref;
2305 stackelement *instanceslot = NULL;
2308 typeinfo *tip = NULL;
2313 fieldref = ref->fieldref;
2316 #ifdef RESOLVE_VERBOSE
2317 fprintf(stderr,"constrain_unresolved_field\n");
2318 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
2319 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
2320 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
2321 fprintf(stderr," class : ");utf_fprint(stderr,fieldref->classref->name);fputc('\n',stderr);
2322 fprintf(stderr," name : ");utf_fprint(stderr,fieldref->name);fputc('\n',stderr);
2323 fprintf(stderr," desc : ");utf_fprint(stderr,fieldref->descriptor);fputc('\n',stderr);
2324 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
2326 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2329 switch (iptr[0].opc) {
2331 instanceslot = stack->prev;
2332 tip = &(stack->typeinfo);
2335 case ICMD_PUTFIELDCONST:
2336 instanceslot = stack;
2339 case ICMD_PUTSTATIC:
2340 tip = &(stack->typeinfo);
2344 instanceslot = stack;
2348 assert(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
2349 fd = fieldref->parseddesc.fd;
2352 /* record subtype constraints for the instance type, if any */
2356 /* The instanceslot must contain a reference to a non-array type */
2357 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
2358 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on non-reference");
2361 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
2362 *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on array");
2366 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2367 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2369 /* The instruction writes a field in an uninitialized object. */
2370 /* This is only allowed when a field of an uninitialized 'this' object is */
2371 /* written inside an initialization method */
2373 classinfo *initclass;
2374 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2377 *exceptionptr = new_verifyerror(refmethod,"accessing field of uninitialized object");
2380 /* XXX check that class of field == refmethod->class */
2381 initclass = refmethod->class; /* XXX classrefs */
2382 assert(initclass->state & CLASS_LOADED);
2383 assert(initclass->state & CLASS_LINKED);
2385 typeinfo_init_classinfo(&tinfo,initclass);
2389 insttip = &(instanceslot->typeinfo);
2391 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2392 &(ref->instancetypes),insttip,fieldref->p.classref))
2396 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2399 /* record subtype constraints for the value type, if any */
2401 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2403 /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
2405 if (INSTRUCTION_PUTCONST_VALUE_ADR(iptr)) {
2406 assert(class_java_lang_String);
2407 assert(class_java_lang_String->state & CLASS_LOADED);
2408 assert(class_java_lang_String->state & CLASS_LINKED);
2409 typeinfo_init_classinfo(&tinfo,class_java_lang_String);
2412 TYPEINFO_INIT_NULLTYPE(tinfo);
2414 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2415 &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref))
2419 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2424 #endif /* ENABLE_VERIFIER */
2426 /* create_unresolved_method ****************************************************
2428 Create an unresolved_method struct for the given method invocation
2431 referer..........the class containing the reference
2432 refmethod........the method triggering the resolution (if any)
2433 iptr.............the INVOKE* instruction
2436 a pointer to a new unresolved_method struct, or
2437 NULL if an exception has been thrown
2439 *******************************************************************************/
2441 unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *refmethod,
2444 unresolved_method *ref;
2445 constant_FMIref *methodref;
2448 methodref = (constant_FMIref *) iptr[0].val.a;
2450 staticmethod = (iptr[0].opc == ICMD_INVOKESTATIC);
2452 #ifdef RESOLVE_VERBOSE
2453 fprintf(stderr,"create_unresolved_method\n");
2454 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
2455 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
2456 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
2457 fprintf(stderr," class : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
2458 fprintf(stderr," name : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
2459 fprintf(stderr," desc : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
2460 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2463 /* allocate params if necessary */
2464 if (!methodref->parseddesc.md->params)
2465 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2466 (staticmethod) ? ACC_STATIC : ACC_NONE))
2469 /* create the data structure */
2470 ref = NEW(unresolved_method);
2471 ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
2472 | ((iptr[0].opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
2473 ref->referermethod = refmethod;
2474 ref->methodref = methodref;
2475 ref->paramconstraints = NULL;
2476 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2481 /* constrain_unresolved_method *************************************************
2483 Record subtype constraints for the arguments of a method call.
2486 ref..............the unresolved_method structure of the call
2487 referer..........the class containing the reference
2488 refmethod........the method triggering the resolution (if any)
2489 iptr.............the INVOKE* instruction
2490 stack............the input stack of the instruction
2493 true.............everything ok
2494 false............an exception has been thrown
2496 *******************************************************************************/
2498 #ifdef ENABLE_VERIFIER
2499 bool constrain_unresolved_method(unresolved_method *ref,
2500 classinfo *referer, methodinfo *refmethod,
2502 stackelement *stack)
2504 constant_FMIref *methodref;
2505 constant_classref *instanceref;
2506 stackelement *instanceslot = NULL;
2507 stackelement *param;
2515 methodref = ref->methodref;
2517 md = methodref->parseddesc.md;
2519 assert(md->params != NULL);
2521 /* XXX clean this up */
2522 instanceref = IS_FMIREF_RESOLVED(methodref)
2523 ? class_get_self_classref(methodref->p.method->class)
2524 : methodref->p.classref;
2526 #ifdef RESOLVE_VERBOSE
2527 fprintf(stderr,"constrain_unresolved_method\n");
2528 fprintf(stderr," referer: ");utf_fprint(stderr,referer->name);fputc('\n',stderr);
2529 fprintf(stderr," rmethod: ");utf_fprint(stderr,refmethod->name);fputc('\n',stderr);
2530 fprintf(stderr," rmdesc : ");utf_fprint(stderr,refmethod->descriptor);fputc('\n',stderr);
2531 fprintf(stderr," class : ");utf_fprint(stderr,methodref->classref->name);fputc('\n',stderr);
2532 fprintf(stderr," name : ");utf_fprint(stderr,methodref->name);fputc('\n',stderr);
2533 fprintf(stderr," desc : ");utf_fprint(stderr,methodref->descriptor);fputc('\n',stderr);
2534 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2537 if ((ref->flags & RESOLVE_STATIC) == 0) {
2538 /* find the instance slot under all the parameter slots on the stack */
2539 instanceslot = stack;
2540 for (i=1; i<md->paramcount; ++i)
2541 instanceslot = instanceslot->prev;
2548 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
2550 /* record subtype constraints for the instance type, if any */
2554 assert(instanceslot->type == TYPE_ADR);
2556 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
2557 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2558 { /* XXX clean up */
2559 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2560 classref_or_classinfo initclass = (ins) ? CLASSREF_OR_CLASSINFO(ins[-1].target)
2561 : CLASSREF_OR_CLASSINFO(refmethod->class);
2563 if (!typeinfo_init_class(tip,initclass))
2567 tip = &(instanceslot->typeinfo);
2569 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2570 &(ref->instancetypes),tip,instanceref))
2574 /* record subtype constraints for the parameter types, if any */
2576 for (i=md->paramcount-1-instancecount; i>=0; --i, param=param->prev) {
2577 type = md->paramtypes[i+instancecount].type;
2580 assert(type == param->type);
2582 if (type == TYPE_ADR) {
2583 if (!ref->paramconstraints) {
2584 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2585 for (j=md->paramcount-1-instancecount; j>i; --j)
2586 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2588 assert(ref->paramconstraints);
2589 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2590 ref->paramconstraints + i,&(param->typeinfo),
2591 md->paramtypes[i+instancecount].classref))
2595 if (ref->paramconstraints)
2596 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2602 #endif /* ENABLE_VERIFIER */
2604 /******************************************************************************/
2605 /* FREEING MEMORY */
2606 /******************************************************************************/
2608 #ifdef ENABLE_VERIFIER
2609 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2612 classref_or_classinfo *p = list;
2614 /* this is silly. we *only* need to count the elements for MFREE */
2617 MFREE(list,classref_or_classinfo,(p - list));
2620 #endif /* ENABLE_VERIFIER */
2622 /* unresolved_class_free *******************************************************
2624 Free the memory used by an unresolved_class
2627 ref..............the unresolved_class
2629 *******************************************************************************/
2631 void unresolved_class_free(unresolved_class *ref)
2635 #ifdef ENABLE_VERIFIER
2636 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2638 FREE(ref,unresolved_class);
2641 /* unresolved_field_free *******************************************************
2643 Free the memory used by an unresolved_field
2646 ref..............the unresolved_field
2648 *******************************************************************************/
2650 void unresolved_field_free(unresolved_field *ref)
2654 #ifdef ENABLE_VERIFIER
2655 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2656 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2658 FREE(ref,unresolved_field);
2661 /* unresolved_method_free ******************************************************
2663 Free the memory used by an unresolved_method
2666 ref..............the unresolved_method
2668 *******************************************************************************/
2670 void unresolved_method_free(unresolved_method *ref)
2674 #ifdef ENABLE_VERIFIER
2675 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2676 if (ref->paramconstraints) {
2678 int count = ref->methodref->parseddesc.md->paramcount;
2680 for (i=0; i<count; ++i)
2681 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2682 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2685 FREE(ref,unresolved_method);
2688 /******************************************************************************/
2690 /******************************************************************************/
2692 #if !defined(NDEBUG)
2694 /* unresolved_subtype_set_debug_dump *******************************************
2696 Print debug info for unresolved_subtype_set to stream
2699 stset............the unresolved_subtype_set
2700 file.............the stream
2702 *******************************************************************************/
2704 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2706 classref_or_classinfo *p;
2708 if (SUBTYPESET_IS_EMPTY(*stset)) {
2709 fprintf(file," (empty)\n");
2712 p = stset->subtyperefs;
2713 for (;p->any; ++p) {
2714 if (IS_CLASSREF(*p)) {
2715 fprintf(file," ref: ");
2716 utf_fprint(file,p->ref->name);
2719 fprintf(file," cls: ");
2720 utf_fprint(file,p->cls->name);
2727 /* unresolved_class_debug_dump *************************************************
2729 Print debug info for unresolved_class to stream
2732 ref..............the unresolved_class
2733 file.............the stream
2735 *******************************************************************************/
2737 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2739 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2741 fprintf(file," referer : ");
2742 utf_fprint(file,ref->classref->referer->name); fputc('\n',file);
2743 fprintf(file," refmethod : ");
2744 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2745 fprintf(file," refmethodd: ");
2746 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2747 fprintf(file," classname : ");
2748 utf_fprint(file,ref->classref->name); fputc('\n',file);
2749 fprintf(file," subtypeconstraints:\n");
2750 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2754 /* unresolved_field_debug_dump *************************************************
2756 Print debug info for unresolved_field to stream
2759 ref..............the unresolved_field
2760 file.............the stream
2762 *******************************************************************************/
2764 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2766 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2768 fprintf(file," referer : ");
2769 utf_fprint(file,ref->referermethod->class->name); fputc('\n',file);
2770 fprintf(file," refmethod : ");
2771 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2772 fprintf(file," refmethodd: ");
2773 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2774 fprintf(file," classname : ");
2775 utf_fprint(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
2776 fprintf(file," name : ");
2777 utf_fprint(file,ref->fieldref->name); fputc('\n',file);
2778 fprintf(file," descriptor: ");
2779 utf_fprint(file,ref->fieldref->descriptor); fputc('\n',file);
2780 fprintf(file," parseddesc: ");
2781 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2782 fprintf(file," flags : %04x\n",ref->flags);
2783 fprintf(file," instancetypes:\n");
2784 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2785 fprintf(file," valueconstraints:\n");
2786 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2790 /* unresolved_method_debug_dump ************************************************
2792 Print debug info for unresolved_method to stream
2795 ref..............the unresolved_method
2796 file.............the stream
2798 *******************************************************************************/
2800 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2804 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2806 fprintf(file," referer : ");
2807 utf_fprint(file,ref->referermethod->class->name); fputc('\n',file);
2808 fprintf(file," refmethod : ");
2809 utf_fprint(file,ref->referermethod->name); fputc('\n',file);
2810 fprintf(file," refmethodd: ");
2811 utf_fprint(file,ref->referermethod->descriptor); fputc('\n',file);
2812 fprintf(file," classname : ");
2813 utf_fprint(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
2814 fprintf(file," name : ");
2815 utf_fprint(file,ref->methodref->name); fputc('\n',file);
2816 fprintf(file," descriptor: ");
2817 utf_fprint(file,ref->methodref->descriptor); fputc('\n',file);
2818 fprintf(file," parseddesc: ");
2819 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2820 fprintf(file," flags : %04x\n",ref->flags);
2821 fprintf(file," instancetypes:\n");
2822 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2823 fprintf(file," paramconstraints:\n");
2824 if (ref->paramconstraints) {
2825 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2826 fprintf(file," param %d:\n",i);
2827 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2831 fprintf(file," (empty)\n");
2835 #endif /* !defined(NDEBUG) */
2838 * These are local overrides for various environment variables in Emacs.
2839 * Please do not remove this and leave it at the end of the file, where
2840 * Emacs will automagically detect them.
2841 * ---------------------------------------------------------------------
2844 * indent-tabs-mode: t
2848 * vim:noexpandtab:sw=4:ts=4: