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 5729 2006-10-09 23:53:42Z edwin $
40 #include "mm/memory.h"
41 #include "vm/resolve.h"
42 #include "vm/access.h"
43 #include "vm/classcache.h"
44 #include "vm/descriptor.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/linker.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/stringlocal.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/verify/typeinfo.h"
55 /******************************************************************************/
57 /******************************************************************************/
59 /*#define RESOLVE_VERBOSE*/
61 /******************************************************************************/
62 /* CLASS RESOLUTION */
63 /******************************************************************************/
65 /* resolve_class_from_name *****************************************************
67 Resolve a symbolic class reference
70 referer..........the class containing the reference
71 refmethod........the method from which resolution was triggered
72 (may be NULL if not applicable)
73 classname........class name to resolve
74 mode.............mode of resolution:
75 resolveLazy...only resolve if it does not
76 require loading classes
77 resolveEager..load classes if necessary
78 checkaccess......if true, access rights to the class are checked
79 link.............if true, guarantee that the returned class, if any,
83 *result..........set to result of resolution, or to NULL if
84 the reference has not been resolved
85 In the case of an exception, *result is
86 guaranteed to be set to NULL.
89 true.............everything ok
90 (*result may still be NULL for resolveLazy)
91 false............an exception has been thrown
94 The returned class is *not* guaranteed to be linked!
95 (It is guaranteed to be loaded, though.)
97 *******************************************************************************/
99 bool resolve_class_from_name(classinfo *referer,
100 methodinfo *refmethod,
107 classinfo *cls = NULL;
114 assert(mode == resolveLazy || mode == resolveEager);
118 #ifdef RESOLVE_VERBOSE
119 printf("resolve_class_from_name(");
120 utf_fprint_printable_ascii(stdout,referer->name);
121 printf(",%p,",(void*)referer->classloader);
122 utf_fprint_printable_ascii(stdout,classname);
123 printf(",%d,%d)\n",(int)checkaccess,(int)link);
126 /* lookup if this class has already been loaded */
128 cls = classcache_lookup(referer->classloader, classname);
130 #ifdef RESOLVE_VERBOSE
131 printf(" lookup result: %p\n",(void*)cls);
135 /* resolve array types */
137 if (classname->text[0] == '[') {
138 utf_ptr = classname->text + 1;
139 len = classname->blength - 1;
141 /* classname is an array type name */
149 /* the component type is a reference type */
150 /* resolve the component type */
151 if (!resolve_class_from_name(referer,refmethod,
152 utf_new(utf_ptr,len),
153 mode,checkaccess,link,&cls))
154 return false; /* exception */
156 assert(mode == resolveLazy);
157 return true; /* be lazy */
159 /* create the array class */
160 cls = class_array_of(cls,false);
162 return false; /* exception */
166 /* the class has not been loaded, yet */
167 if (mode == resolveLazy)
168 return true; /* be lazy */
171 #ifdef RESOLVE_VERBOSE
172 printf(" loading...\n");
177 if (!(cls = load_class_from_classloader(classname,
178 referer->classloader)))
179 return false; /* exception */
183 /* the class is now loaded */
185 assert(cls->state & CLASS_LOADED);
187 #ifdef RESOLVE_VERBOSE
188 printf(" checking access rights...\n");
191 /* check access rights of referer to refered class */
192 if (checkaccess && !access_is_accessible_class(referer,cls)) {
196 msglen = utf_bytes(cls->name) + utf_bytes(referer->name) + 100;
197 message = MNEW(char, msglen);
198 strcpy(message, "class is not accessible (");
199 utf_cat_classname(message, cls->name);
200 strcat(message, " from ");
201 utf_cat_classname(message, referer->name);
202 strcat(message, ")");
203 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
204 MFREE(message,char,msglen);
205 return false; /* exception */
208 /* link the class if necessary */
210 if (!(cls->state & CLASS_LINKED))
211 if (!link_class(cls))
212 return false; /* exception */
214 assert(cls->state & CLASS_LINKED);
217 /* resolution succeeds */
218 #ifdef RESOLVE_VERBOSE
219 printf(" success.\n");
225 /* resolve_classref ************************************************************
227 Resolve a symbolic class reference
230 refmethod........the method from which resolution was triggered
231 (may be NULL if not applicable)
232 ref..............class reference
233 mode.............mode of resolution:
234 resolveLazy...only resolve if it does not
235 require loading classes
236 resolveEager..load classes if necessary
237 checkaccess......if true, access rights to the class are checked
238 link.............if true, guarantee that the returned class, if any,
242 *result..........set to result of resolution, or to NULL if
243 the reference has not been resolved
244 In the case of an exception, *result is
245 guaranteed to be set to NULL.
248 true.............everything ok
249 (*result may still be NULL for resolveLazy)
250 false............an exception has been thrown
252 *******************************************************************************/
254 bool resolve_classref(methodinfo *refmethod,
255 constant_classref *ref,
261 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
264 /* resolve_classref_or_classinfo ***********************************************
266 Resolve a symbolic class reference if necessary
269 refmethod........the method from which resolution was triggered
270 (may be NULL if not applicable)
271 cls..............class reference or classinfo
272 mode.............mode of resolution:
273 resolveLazy...only resolve if it does not
274 require loading classes
275 resolveEager..load classes if necessary
276 checkaccess......if true, access rights to the class are checked
277 link.............if true, guarantee that the returned class, if any,
281 *result..........set to result of resolution, or to NULL if
282 the reference has not been resolved
283 In the case of an exception, *result is
284 guaranteed to be set to NULL.
287 true.............everything ok
288 (*result may still be NULL for resolveLazy)
289 false............an exception has been thrown
291 *******************************************************************************/
293 bool resolve_classref_or_classinfo(methodinfo *refmethod,
294 classref_or_classinfo cls,
303 assert(mode == resolveEager || mode == resolveLazy);
306 #ifdef RESOLVE_VERBOSE
307 printf("resolve_classref_or_classinfo(");
308 utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
309 printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
314 if (IS_CLASSREF(cls)) {
315 /* we must resolve this reference */
317 if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
318 mode, checkaccess, link, &c))
319 goto return_exception;
322 /* cls has already been resolved */
324 assert(c->state & CLASS_LOADED);
326 assert(c || (mode == resolveLazy));
329 return true; /* be lazy */
332 assert(c->state & CLASS_LOADED);
335 if (!(c->state & CLASS_LINKED))
337 goto return_exception;
339 assert(c->state & CLASS_LINKED);
352 /* resolve_class_from_typedesc *************************************************
354 Return a classinfo * for the given type descriptor
357 d................type descriptor
358 checkaccess......if true, access rights to the class are checked
359 link.............if true, guarantee that the returned class, if any,
362 *result..........set to result of resolution, or to NULL if
363 the reference has not been resolved
364 In the case of an exception, *result is
365 guaranteed to be set to NULL.
368 true.............everything ok
369 false............an exception has been thrown
372 This function always resolves eagerly.
374 *******************************************************************************/
376 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
385 #ifdef RESOLVE_VERBOSE
386 printf("resolve_class_from_typedesc(");
387 descriptor_debug_print_typedesc(stdout,d);
388 printf(",%i,%i)\n",(int)checkaccess,(int)link);
391 if (d->type == TYPE_ADR) {
392 /* a reference type */
394 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
395 resolveEager,checkaccess,link,&cls))
396 return false; /* exception */
399 /* a primitive type */
400 cls = primitivetype_table[d->decltype].class_primitive;
401 assert(cls->state & CLASS_LOADED);
402 if (!(cls->state & CLASS_LINKED))
403 if (!link_class(cls))
404 return false; /* exception */
407 assert(cls->state & CLASS_LOADED);
408 assert(!link || (cls->state & CLASS_LINKED));
410 #ifdef RESOLVE_VERBOSE
411 printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
418 /******************************************************************************/
419 /* SUBTYPE SET CHECKS */
420 /******************************************************************************/
422 /* resolve_subtype_check *******************************************************
424 Resolve the given types lazily and perform a subtype check
427 refmethod........the method triggering the resolution
428 subtype..........checked to be a subtype of supertype
429 supertype........the super type to check agaings
430 mode.............mode of resolution:
431 resolveLazy...only resolve if it does not
432 require loading classes
433 resolveEager..load classes if necessary
434 error............which type of exception to throw if
435 the test fails. May be:
436 resolveLinkageError, or
437 resolveIllegalAccessError
438 IMPORTANT: If error==resolveIllegalAccessError,
439 then array types are not checked.
442 resolveSucceeded.....the check succeeded
443 resolveDeferred......the check could not be performed due to
444 unresolved types. (This can only happen for
445 mode == resolveLazy.)
446 resolveFailed........the check failed, an exception has been thrown.
449 The types are resolved first, so any
450 exception which may occurr during resolution may
451 be thrown by this function.
453 *******************************************************************************/
455 #if defined(ENABLE_VERIFIER)
456 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
457 classref_or_classinfo subtype,
458 classref_or_classinfo supertype,
468 assert(supertype.any);
469 assert(mode == resolveLazy || mode == resolveEager);
470 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
472 /* resolve the subtype */
474 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
475 /* the subclass could not be resolved. therefore we are sure that */
476 /* no instances of this subclass will ever exist -> skip this test */
477 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
478 *exceptionptr = NULL;
479 return resolveSucceeded;
482 return resolveDeferred; /* be lazy */
484 assert(subclass->state & CLASS_LINKED);
486 /* do not check access to protected members of arrays */
488 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
489 return resolveSucceeded;
492 /* perform the subtype check */
494 typeinfo_init_classinfo(&subti,subclass);
496 r = typeinfo_is_assignable_to_class(&subti,supertype);
497 if (r == typecheck_FAIL)
498 return resolveFailed; /* failed, exception is already set */
500 if (r == typecheck_MAYBE) {
501 assert(IS_CLASSREF(supertype));
502 if (mode == resolveEager) {
503 if (!resolve_classref_or_classinfo(refmethod,supertype,
504 resolveEager,false,true,
507 return resolveFailed;
509 assert(supertype.cls);
513 return resolveDeferred; /* be lazy */
517 /* sub class relationship is false */
522 #if defined(RESOLVE_VERBOSE)
523 printf("SUBTYPE CHECK FAILED!\n");
526 msglen = utf_bytes(subclass->name) + utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype)) + 200;
527 message = MNEW(char, msglen);
528 strcpy(message, (error == resolveIllegalAccessError) ?
529 "illegal access to protected member ("
530 : "subtype constraint violated (");
531 utf_cat_classname(message, subclass->name);
532 strcat(message, " is not a subclass of ");
533 utf_cat_classname(message, CLASSREF_OR_CLASSINFO_NAME(supertype));
534 strcat(message, ")");
535 if (error == resolveIllegalAccessError)
536 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
538 *exceptionptr = exceptions_new_linkageerror(message, NULL);
539 MFREE(message, char, msglen);
540 return resolveFailed; /* exception */
545 return resolveSucceeded;
547 #endif /* defined(ENABLE_VERIFIER) */
549 /* resolve_lazy_subtype_checks *************************************************
551 Resolve the types to check lazily and perform subtype checks
554 refmethod........the method triggering the resolution
555 subtinfo.........the typeinfo containing the subtypes
556 supertype........the supertype to test againgst
557 mode.............mode of resolution:
558 resolveLazy...only resolve if it does not
559 require loading classes
560 resolveEager..load classes if necessary
561 error............which type of exception to throw if
562 the test fails. May be:
563 resolveLinkageError, or
564 resolveIllegalAccessError
565 IMPORTANT: If error==resolveIllegalAccessError,
566 then array types in the set are skipped.
569 resolveSucceeded.....the check succeeded
570 resolveDeferred......the check could not be performed due to
572 resolveFailed........the check failed, an exception has been thrown.
575 The references in the set are resolved first, so any
576 exception which may occurr during resolution may
577 be thrown by this function.
579 *******************************************************************************/
581 #if defined(ENABLE_VERIFIER)
582 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
584 classref_or_classinfo supertype,
589 resolve_result_t result;
593 assert(supertype.any);
594 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
596 /* returnAddresses are illegal here */
598 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
599 exceptions_throw_verifyerror(refmethod,
600 "Invalid use of returnAddress");
601 return resolveFailed;
604 /* uninitialized objects are illegal here */
606 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
607 exceptions_throw_verifyerror(refmethod,
608 "Invalid use of uninitialized object");
609 return resolveFailed;
612 /* the nulltype is always assignable */
614 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
615 return resolveSucceeded;
617 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
619 if (supertype.cls == class_java_lang_Object
620 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
621 && refmethod->class->classloader == NULL))
623 return resolveSucceeded;
626 if (subtinfo->merged) {
628 /* for a merged type we have to do a series of checks */
630 count = subtinfo->merged->count;
631 for (i=0; i<count; ++i) {
632 classref_or_classinfo c = subtinfo->merged->list[i];
633 if (subtinfo->dimension > 0) {
634 /* a merge of array types */
635 /* the merged list contains the possible _element_ types, */
636 /* so we have to create array types with these elements. */
637 if (IS_CLASSREF(c)) {
638 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
641 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
645 /* do the subtype check against the type c */
647 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
648 if (result != resolveSucceeded)
654 /* a single type, this is the common case, hopefully */
656 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
657 == CLASSREF_OR_CLASSINFO_NAME(supertype))
659 /* the class names are the same */
660 /* equality is guaranteed by the loading constraints */
661 return resolveSucceeded;
665 /* some other type name, try to perform the check lazily */
667 return resolve_subtype_check(refmethod,
668 subtinfo->typeclass,supertype,
675 return resolveSucceeded;
677 #endif /* defined(ENABLE_VERIFIER) */
679 /* resolve_and_check_subtype_set ***********************************************
681 Resolve the references in the given set and test subtype relationships
684 refmethod........the method triggering the resolution
685 ref..............a set of class/interface references
687 typeref..........the type to test against the set
688 mode.............mode of resolution:
689 resolveLazy...only resolve if it does not
690 require loading classes
691 resolveEager..load classes if necessary
692 error............which type of exception to throw if
693 the test fails. May be:
694 resolveLinkageError, or
695 resolveIllegalAccessError
696 IMPORTANT: If error==resolveIllegalAccessError,
697 then array types in the set are skipped.
700 resolveSucceeded.....the check succeeded
701 resolveDeferred......the check could not be performed due to
702 unresolved types. (This can only happen if
703 mode == resolveLazy.)
704 resolveFailed........the check failed, an exception has been thrown.
707 The references in the set are resolved first, so any
708 exception which may occurr during resolution may
709 be thrown by this function.
711 *******************************************************************************/
713 #if defined(ENABLE_VERIFIER)
714 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
715 unresolved_subtype_set *ref,
716 classref_or_classinfo typeref,
720 classref_or_classinfo *setp;
721 typecheck_result checkresult;
726 assert(mode == resolveLazy || mode == resolveEager);
727 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
729 #if defined(RESOLVE_VERBOSE)
730 printf("resolve_and_check_subtype_set:\n");
731 unresolved_subtype_set_debug_dump(ref, stdout);
732 if (IS_CLASSREF(typeref))
733 class_classref_println(typeref.ref);
735 class_println(typeref.cls);
738 setp = ref->subtyperefs;
740 /* an empty set of tests always succeeds */
741 if (!setp || !setp->any) {
742 return resolveSucceeded;
745 /* first resolve the type if necessary */
746 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
747 return resolveFailed; /* exception */
749 return resolveDeferred; /* be lazy */
751 assert(typeref.cls->state & CLASS_LINKED);
753 /* iterate over the set members */
755 for (; setp->any; ++setp) {
756 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
757 #if defined(RESOLVE_VERBOSE)
758 if (checkresult != resolveSucceeded)
759 printf("SUBTYPE CHECK FAILED!\n");
761 if (checkresult != resolveSucceeded)
766 return resolveSucceeded;
768 #endif /* defined(ENABLE_VERIFIER) */
770 /******************************************************************************/
771 /* CLASS RESOLUTION */
772 /******************************************************************************/
774 /* resolve_class ***************************************************************
776 Resolve an unresolved class reference. The class is also linked.
779 ref..............struct containing the reference
780 mode.............mode of resolution:
781 resolveLazy...only resolve if it does not
782 require loading classes
783 resolveEager..load classes if necessary
784 checkaccess......if true, access rights to the class are checked
787 *result..........set to the result of resolution, or to NULL if
788 the reference has not been resolved
789 In the case of an exception, *result is
790 guaranteed to be set to NULL.
793 true.............everything ok
794 (*result may still be NULL for resolveLazy)
795 false............an exception has been thrown
797 *******************************************************************************/
799 #ifdef ENABLE_VERIFIER
800 bool resolve_class(unresolved_class *ref,
806 resolve_result_t checkresult;
810 assert(mode == resolveLazy || mode == resolveEager);
814 #ifdef RESOLVE_VERBOSE
815 unresolved_class_debug_dump(ref,stdout);
818 /* first we must resolve the class */
819 if (!resolve_classref(ref->referermethod,
820 ref->classref,mode,checkaccess,true,&cls))
822 /* the class reference could not be resolved */
823 return false; /* exception */
826 return true; /* be lazy */
829 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
831 /* now we check the subtype constraints */
833 checkresult = resolve_and_check_subtype_set(ref->referermethod,
834 &(ref->subtypeconstraints),
835 CLASSREF_OR_CLASSINFO(cls),
837 resolveLinkageError);
838 if (checkresult != resolveSucceeded)
839 return (bool) checkresult;
845 #endif /* ENABLE_VERIFIER */
847 /* resolve_classref_eager ******************************************************
849 Resolve an unresolved class reference eagerly. The class is also linked and
850 access rights to the class are checked.
853 ref..............constant_classref to the class
856 classinfo * to the class, or
857 NULL if an exception has been thrown
859 *******************************************************************************/
861 classinfo * resolve_classref_eager(constant_classref *ref)
865 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
871 /* resolve_classref_eager_nonabstract ******************************************
873 Resolve an unresolved class reference eagerly. The class is also linked and
874 access rights to the class are checked. A check is performed that the class
878 ref..............constant_classref to the class
881 classinfo * to the class, or
882 NULL if an exception has been thrown
884 *******************************************************************************/
886 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
890 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
893 /* ensure that the class is not abstract */
895 if (c->flags & ACC_ABSTRACT) {
896 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
903 /* resolve_class_eager *********************************************************
905 Resolve an unresolved class reference eagerly. The class is also linked and
906 access rights to the class are checked.
909 ref..............struct containing the reference
912 classinfo * to the class, or
913 NULL if an exception has been thrown
915 *******************************************************************************/
917 #ifdef ENABLE_VERIFIER
918 classinfo * resolve_class_eager(unresolved_class *ref)
922 if (!resolve_class(ref,resolveEager,true,&c))
927 #endif /* ENABLE_VERIFIER */
929 /******************************************************************************/
930 /* FIELD RESOLUTION */
931 /******************************************************************************/
933 /* resolve_field_verifier_checks *******************************************
935 Do the verifier checks necessary after field has been resolved.
938 refmethod........the method containing the reference
939 fieldref.........the field reference
940 container........the class where the field was found
941 fi...............the fieldinfo of the resolved field
942 instanceti.......instance typeinfo, if available
943 valueti..........value typeinfo, if available
944 isstatic.........true if this is a *STATIC* instruction
945 isput............true if this is a PUT* instruction
948 resolveSucceeded....everything ok
949 resolveDeferred.....tests could not be done, have been deferred
950 resolveFailed.......exception has been thrown
952 *******************************************************************************/
954 #if defined(ENABLE_VERIFIER)
955 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
956 constant_FMIref *fieldref,
957 classinfo *container,
959 typeinfo *instanceti,
966 resolve_result_t result;
967 constant_classref *fieldtyperef;
974 /* get the classinfos and the field type */
976 referer = refmethod->class;
979 declarer = fi->class;
981 assert(referer->state & CLASS_LINKED);
983 fieldtyperef = fieldref->parseddesc.fd->classref;
988 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
991 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
992 /* a static field is accessed via an instance, or vice versa */
994 new_exception_message(string_java_lang_IncompatibleClassChangeError,
995 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
996 : "instance field accessed without instance");
997 return resolveFailed;
1000 /* check access rights */
1002 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1006 msglen = utf_bytes(declarer->name) + utf_bytes(fi->name) + utf_bytes(referer->name) + 100;
1007 message = MNEW(char, msglen);
1008 strcpy(message, "field is not accessible (");
1009 utf_cat_classname(message, declarer->name);
1010 strcat(message, ".");
1011 utf_cat(message, fi->name);
1012 strcat(message, " from ");
1013 utf_cat_classname(message, referer->name);
1014 strcat(message, ")");
1015 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1016 MFREE(message,char,msglen);
1017 return resolveFailed; /* exception */
1020 /* for non-static methods we have to check the constraints on the */
1027 /* The instanceslot must contain a reference to a non-array type */
1029 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
1030 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1031 return resolveFailed;
1033 if (TYPEINFO_IS_ARRAY(*instanceti)) {
1034 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1035 return resolveFailed;
1038 if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
1040 /* The instruction writes a field in an uninitialized object. */
1041 /* This is only allowed when a field of an uninitialized 'this' object is */
1042 /* written inside an initialization method */
1044 classinfo *initclass;
1045 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1048 exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1049 return resolveFailed;
1052 /* XXX check that class of field == refmethod->class */
1053 initclass = referer; /* XXX classrefs */
1054 assert(initclass->state & CLASS_LINKED);
1056 typeinfo_init_classinfo(&tinfo, initclass);
1060 insttip = instanceti;
1063 result = resolve_lazy_subtype_checks(refmethod,
1065 CLASSREF_OR_CLASSINFO(container),
1066 resolveLinkageError);
1067 if (result != resolveSucceeded)
1070 /* check protected access */
1072 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1074 result = resolve_lazy_subtype_checks(refmethod,
1076 CLASSREF_OR_CLASSINFO(referer),
1077 resolveIllegalAccessError);
1078 if (result != resolveSucceeded)
1084 /* for PUT* instructions we have to check the constraints on the value type */
1087 assert(fieldtyperef);
1089 /* check subtype constraints */
1090 result = resolve_lazy_subtype_checks(refmethod,
1092 CLASSREF_OR_CLASSINFO(fieldtyperef),
1093 resolveLinkageError);
1095 if (result != resolveSucceeded)
1099 /* impose loading constraint on field type */
1101 if (fi->type == TYPE_ADR) {
1102 assert(fieldtyperef);
1103 if (!classcache_add_constraint(declarer->classloader,
1104 referer->classloader,
1105 fieldtyperef->name))
1106 return resolveFailed;
1109 /* XXX impose loading constraint on instance? */
1112 return resolveSucceeded;
1114 #endif /* defined(ENABLE_VERIFIER) */
1116 /* resolve_field_lazy **********************************************************
1118 Resolve an unresolved field reference lazily
1120 NOTE: This function does NOT do any verification checks. In case of a
1121 successful resolution, you must call resolve_field_verifier_checks
1122 in order to perform the necessary checks!
1125 refmethod........the referer method
1126 fieldref.........the field reference
1129 resolveSucceeded.....the reference has been resolved
1130 resolveDeferred......the resolving could not be performed lazily
1131 resolveFailed........resolving failed, an exception has been thrown.
1133 *******************************************************************************/
1135 resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1136 constant_FMIref *fieldref)
1139 classinfo *container;
1144 /* the class containing the reference */
1146 referer = refmethod->class;
1149 /* check if the field itself is already resolved */
1151 if (IS_FMIREF_RESOLVED(fieldref))
1152 return resolveSucceeded;
1154 /* first we must resolve the class containg the field */
1156 /* XXX can/may lazyResolving trigger linking? */
1158 if (!resolve_class_from_name(referer, refmethod,
1159 fieldref->p.classref->name, resolveLazy, true, true, &container))
1161 /* the class reference could not be resolved */
1162 return resolveFailed; /* exception */
1165 return resolveDeferred; /* be lazy */
1167 assert(container->state & CLASS_LINKED);
1169 /* now we must find the declaration of the field in `container`
1170 * or one of its superclasses */
1172 fi = class_resolvefield(container,
1173 fieldref->name, fieldref->descriptor,
1176 /* The field does not exist. But since we were called lazily, */
1177 /* this error must not be reported now. (It will be reported */
1178 /* if eager resolving of this field is ever tried.) */
1180 *exceptionptr = NULL;
1181 return resolveDeferred; /* be lazy */
1184 /* cache the result of the resolution */
1186 fieldref->p.field = fi;
1189 return resolveSucceeded;
1192 /* resolve_field ***************************************************************
1194 Resolve an unresolved field reference
1197 ref..............struct containing the reference
1198 mode.............mode of resolution:
1199 resolveLazy...only resolve if it does not
1200 require loading classes
1201 resolveEager..load classes if necessary
1204 *result..........set to the result of resolution, or to NULL if
1205 the reference has not been resolved
1206 In the case of an exception, *result is
1207 guaranteed to be set to NULL.
1210 true.............everything ok
1211 (*result may still be NULL for resolveLazy)
1212 false............an exception has been thrown
1214 *******************************************************************************/
1216 bool resolve_field(unresolved_field *ref,
1217 resolve_mode_t mode,
1221 classinfo *container;
1222 classinfo *declarer;
1223 constant_classref *fieldtyperef;
1225 resolve_result_t checkresult;
1229 assert(mode == resolveLazy || mode == resolveEager);
1233 #ifdef RESOLVE_VERBOSE
1234 unresolved_field_debug_dump(ref,stdout);
1237 /* the class containing the reference */
1239 referer = ref->referermethod->class;
1242 /* check if the field itself is already resolved */
1243 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1244 fi = ref->fieldref->p.field;
1245 container = fi->class;
1246 goto resolved_the_field;
1249 /* first we must resolve the class containg the field */
1250 if (!resolve_class_from_name(referer,ref->referermethod,
1251 ref->fieldref->p.classref->name,mode,true,true,&container))
1253 /* the class reference could not be resolved */
1254 return false; /* exception */
1257 return true; /* be lazy */
1260 assert(container->state & CLASS_LOADED);
1261 assert(container->state & CLASS_LINKED);
1263 /* now we must find the declaration of the field in `container`
1264 * or one of its superclasses */
1266 #ifdef RESOLVE_VERBOSE
1267 printf(" resolving field in class...\n");
1270 fi = class_resolvefield(container,
1271 ref->fieldref->name,ref->fieldref->descriptor,
1274 if (mode == resolveLazy) {
1275 /* The field does not exist. But since we were called lazily, */
1276 /* this error must not be reported now. (It will be reported */
1277 /* if eager resolving of this field is ever tried.) */
1279 *exceptionptr = NULL;
1280 return true; /* be lazy */
1283 return false; /* exception */
1286 /* cache the result of the resolution */
1287 ref->fieldref->p.field = fi;
1291 #ifdef ENABLE_VERIFIER
1292 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1293 /* that no missing parts of an instruction will be accessed. */
1295 checkresult = resolve_field_verifier_checks(
1300 NULL, /* instanceti, handled by constraints below */
1301 NULL, /* valueti, handled by constraints below */
1302 (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1303 (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1305 if (checkresult != resolveSucceeded)
1306 return (bool) checkresult;
1308 declarer = fi->class;
1310 assert(declarer->state & CLASS_LOADED);
1311 assert(declarer->state & CLASS_LINKED);
1313 /* for non-static accesses we have to check the constraints on the */
1316 if (!(ref->flags & RESOLVE_STATIC)) {
1317 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1318 &(ref->instancetypes),
1319 CLASSREF_OR_CLASSINFO(container),
1320 mode, resolveLinkageError);
1321 if (checkresult != resolveSucceeded)
1322 return (bool) checkresult;
1325 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1327 /* for PUT* instructions we have to check the constraints on the value type */
1328 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1329 assert(fieldtyperef);
1330 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1331 /* check subtype constraints */
1332 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1333 &(ref->valueconstraints),
1334 CLASSREF_OR_CLASSINFO(fieldtyperef),
1335 mode, resolveLinkageError);
1336 if (checkresult != resolveSucceeded)
1337 return (bool) checkresult;
1341 /* check protected access */
1342 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1343 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1344 &(ref->instancetypes),
1345 CLASSREF_OR_CLASSINFO(referer),
1347 resolveIllegalAccessError);
1348 if (checkresult != resolveSucceeded)
1349 return (bool) checkresult;
1353 #endif /* ENABLE_VERIFIER */
1361 /* resolve_field_eager *********************************************************
1363 Resolve an unresolved field reference eagerly.
1366 ref..............struct containing the reference
1369 fieldinfo * to the field, or
1370 NULL if an exception has been thrown
1372 *******************************************************************************/
1374 fieldinfo * resolve_field_eager(unresolved_field *ref)
1378 if (!resolve_field(ref,resolveEager,&fi))
1384 /******************************************************************************/
1385 /* METHOD RESOLUTION */
1386 /******************************************************************************/
1388 /* resolve_method_invokespecial_lookup *****************************************
1390 Do the special lookup for methods invoked by INVOKESPECIAL
1393 refmethod........the method containing the reference
1394 mi...............the methodinfo of the resolved method
1397 a methodinfo *...the result of the lookup,
1398 NULL.............an exception has been thrown
1400 *******************************************************************************/
1402 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1405 classinfo *declarer;
1411 /* get referer and declarer classes */
1413 referer = refmethod->class;
1416 declarer = mi->class;
1418 assert(referer->state & CLASS_LINKED);
1420 /* checks for INVOKESPECIAL: */
1421 /* for <init> and methods of the current class we don't need any */
1422 /* special checks. Otherwise we must verify that the called method */
1423 /* belongs to a super class of the current class */
1425 if ((referer != declarer) && (mi->name != utf_init)) {
1426 /* check that declarer is a super class of the current class */
1428 if (!class_issubclass(referer,declarer)) {
1429 exceptions_throw_verifyerror(refmethod,
1430 "INVOKESPECIAL calling non-super class method");
1434 /* if the referer has ACC_SUPER set, we must do the special */
1435 /* lookup starting with the direct super class of referer */
1437 if ((referer->flags & ACC_SUPER) != 0) {
1438 mi = class_resolvemethod(referer->super.cls,
1443 /* the spec calls for an AbstractMethodError in this case */
1444 exceptions_throw_abstractmethoderror();
1454 /* resolve_method_verifier_checks ******************************************
1456 Do the verifier checks necessary after a method has been resolved.
1459 refmethod........the method containing the reference
1460 methodref........the method reference
1461 mi...............the methodinfo of the resolved method
1462 invokestatic.....true if the method is invoked by INVOKESTATIC
1465 resolveSucceeded....everything ok
1466 resolveDeferred.....tests could not be done, have been deferred
1467 resolveFailed.......exception has been thrown
1469 *******************************************************************************/
1471 #if defined(ENABLE_VERIFIER)
1472 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1473 constant_FMIref *methodref,
1477 classinfo *declarer;
1484 #ifdef RESOLVE_VERBOSE
1485 printf("resolve_method_verifier_checks\n");
1486 printf(" flags: %02x\n",mi->flags);
1489 /* get the classinfos and the method descriptor */
1491 referer = refmethod->class;
1494 declarer = mi->class;
1499 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1500 /* a static method is accessed via an instance, or vice versa */
1502 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1503 (mi->flags & ACC_STATIC) ? "static method called via instance"
1504 : "instance method called without instance");
1505 return resolveFailed;
1508 /* check access rights */
1510 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1514 /* XXX clean this up. this should be in exceptions.c */
1515 msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
1516 utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
1517 message = MNEW(char, msglen);
1518 strcpy(message, "method is not accessible (");
1519 utf_cat_classname(message, declarer->name);
1520 strcat(message, ".");
1521 utf_cat(message, mi->name);
1522 utf_cat(message, mi->descriptor);
1523 strcat(message," from ");
1524 utf_cat_classname(message, referer->name);
1525 strcat(message,")");
1526 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1527 MFREE(message, char, msglen);
1528 return resolveFailed; /* exception */
1533 return resolveSucceeded;
1535 #endif /* defined(ENABLE_VERIFIER) */
1538 /* resolve_method_instance_type_checks *****************************************
1540 Check the instance type of a method invocation.
1543 refmethod........the method containing the reference
1544 mi...............the methodinfo of the resolved method
1545 instanceti.......typeinfo of the instance slot
1546 invokespecial....true if the method is invoked by INVOKESPECIAL
1549 resolveSucceeded....everything ok
1550 resolveDeferred.....tests could not be done, have been deferred
1551 resolveFailed.......exception has been thrown
1553 *******************************************************************************/
1555 #if defined(ENABLE_VERIFIER)
1556 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1558 typeinfo *instanceti,
1563 resolve_result_t result;
1565 if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
1566 { /* XXX clean up */
1567 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
1568 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1569 : CLASSREF_OR_CLASSINFO(refmethod->class);
1571 if (!typeinfo_init_class(tip, initclass))
1578 result = resolve_lazy_subtype_checks(refmethod,
1580 CLASSREF_OR_CLASSINFO(mi->class),
1581 resolveLinkageError);
1582 if (result != resolveSucceeded)
1585 /* check protected access */
1587 /* XXX use other `declarer` than mi->class? */
1588 if (((mi->flags & ACC_PROTECTED) != 0)
1589 && !SAME_PACKAGE(mi->class, refmethod->class))
1591 result = resolve_lazy_subtype_checks(refmethod,
1593 CLASSREF_OR_CLASSINFO(refmethod->class),
1594 resolveIllegalAccessError);
1595 if (result != resolveSucceeded)
1601 return resolveSucceeded;
1603 #endif /* defined(ENABLE_VERIFIER) */
1606 /* resolve_method_param_type_checks ********************************************
1608 Check non-instance parameter types of a method invocation.
1611 jd...............jitdata of the method doing the call
1612 refmethod........the method containing the reference
1613 iptr.............the invoke instruction
1614 mi...............the methodinfo of the resolved method
1615 invokestatic.....true if the method is invoked by INVOKESTATIC
1618 resolveSucceeded....everything ok
1619 resolveDeferred.....tests could not be done, have been deferred
1620 resolveFailed.......exception has been thrown
1622 *******************************************************************************/
1624 #if defined(ENABLE_VERIFIER)
1625 resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1626 methodinfo *refmethod,
1632 resolve_result_t result;
1634 typedesc *paramtypes;
1641 instancecount = (invokestatic) ? 0 : 1;
1643 /* check subtype constraints for TYPE_ADR parameters */
1645 md = mi->parseddesc;
1646 paramtypes = md->paramtypes;
1648 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1649 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1650 type = md->paramtypes[i+instancecount].type;
1653 assert(type == param->type);
1655 if (type == TYPE_ADR) {
1656 result = resolve_lazy_subtype_checks(refmethod,
1658 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1659 resolveLinkageError);
1660 if (result != resolveSucceeded)
1667 return resolveSucceeded;
1669 #endif /* defined(ENABLE_VERIFIER) */
1672 /* resolve_method_loading_constraints ******************************************
1674 Impose loading constraints on the parameters and return type of the
1678 referer..........the class refering to the method
1679 mi...............the method
1682 true................everything ok
1683 false...............an exception has been thrown
1685 *******************************************************************************/
1687 #if defined(ENABLE_VERIFIER)
1688 bool resolve_method_loading_constraints(classinfo *referer,
1692 typedesc *paramtypes;
1697 /* impose loading constraints on parameters (including instance) */
1699 md = mi->parseddesc;
1700 paramtypes = md->paramtypes;
1701 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1703 for (i = 0; i < md->paramcount; i++) {
1704 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1705 if (i < instancecount) {
1706 /* The type of the 'this' pointer is the class containing */
1707 /* the method definition. Since container is the same as, */
1708 /* or a subclass of declarer, we also constrain declarer */
1709 /* by transitivity of loading constraints. */
1710 name = mi->class->name;
1713 name = paramtypes[i].classref->name;
1716 /* The caller (referer) and the callee (container) must agree */
1717 /* on the types of the parameters. */
1718 if (!classcache_add_constraint(referer->classloader,
1719 mi->class->classloader, name))
1720 return false; /* exception */
1724 /* impose loading constraint onto return type */
1726 if (md->returntype.type == TYPE_ADR) {
1727 /* The caller (referer) and the callee (container) must agree */
1728 /* on the return type. */
1729 if (!classcache_add_constraint(referer->classloader,
1730 mi->class->classloader,
1731 md->returntype.classref->name))
1732 return false; /* exception */
1739 #endif /* defined(ENABLE_VERIFIER) */
1742 /* resolve_method_lazy *********************************************************
1744 Resolve an unresolved method reference lazily
1746 NOTE: This function does NOT do any verification checks. In case of a
1747 successful resolution, you must call resolve_method_verifier_checks
1748 in order to perform the necessary checks!
1751 refmethod........the referer method
1752 methodref........the method reference
1753 invokespecial....true if this is an INVOKESPECIAL instruction
1756 resolveSucceeded.....the reference has been resolved
1757 resolveDeferred......the resolving could not be performed lazily
1758 resolveFailed........resolving failed, an exception has been thrown.
1760 *******************************************************************************/
1762 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1763 constant_FMIref *methodref,
1767 classinfo *container;
1772 #ifdef RESOLVE_VERBOSE
1773 printf("resolve_method_lazy\n");
1776 /* the class containing the reference */
1778 referer = refmethod->class;
1781 /* check if the method itself is already resolved */
1783 if (IS_FMIREF_RESOLVED(methodref))
1784 return resolveSucceeded;
1786 /* first we must resolve the class containg the method */
1788 if (!resolve_class_from_name(referer, refmethod,
1789 methodref->p.classref->name, resolveLazy, true, true, &container))
1791 /* the class reference could not be resolved */
1792 return resolveFailed; /* exception */
1795 return resolveDeferred; /* be lazy */
1797 assert(container->state & CLASS_LINKED);
1799 /* now we must find the declaration of the method in `container`
1800 * or one of its superclasses */
1802 if (container->flags & ACC_INTERFACE) {
1803 mi = class_resolveinterfacemethod(container,
1805 methodref->descriptor,
1809 mi = class_resolveclassmethod(container,
1811 methodref->descriptor,
1816 /* The method does not exist. But since we were called lazily, */
1817 /* this error must not be reported now. (It will be reported */
1818 /* if eager resolving of this method is ever tried.) */
1820 *exceptionptr = NULL;
1821 return resolveDeferred; /* be lazy */
1824 if (invokespecial) {
1825 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1827 return resolveFailed; /* exception */
1830 /* have the method params already been parsed? no, do it. */
1832 if (!mi->parseddesc->params)
1833 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1834 return resolveFailed;
1836 /* cache the result of the resolution */
1838 methodref->p.method = mi;
1842 return resolveSucceeded;
1845 /* resolve_method **************************************************************
1847 Resolve an unresolved method reference
1850 ref..............struct containing the reference
1851 mode.............mode of resolution:
1852 resolveLazy...only resolve if it does not
1853 require loading classes
1854 resolveEager..load classes if necessary
1857 *result..........set to the result of resolution, or to NULL if
1858 the reference has not been resolved
1859 In the case of an exception, *result is
1860 guaranteed to be set to NULL.
1863 true.............everything ok
1864 (*result may still be NULL for resolveLazy)
1865 false............an exception has been thrown
1867 *******************************************************************************/
1869 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1872 classinfo *container;
1873 classinfo *declarer;
1875 typedesc *paramtypes;
1878 resolve_result_t checkresult;
1882 assert(mode == resolveLazy || mode == resolveEager);
1884 #ifdef RESOLVE_VERBOSE
1885 unresolved_method_debug_dump(ref,stdout);
1890 /* the class containing the reference */
1892 referer = ref->referermethod->class;
1895 /* check if the method itself is already resolved */
1897 if (IS_FMIREF_RESOLVED(ref->methodref)) {
1898 mi = ref->methodref->p.method;
1899 container = mi->class;
1900 goto resolved_the_method;
1903 /* first we must resolve the class containing the method */
1905 if (!resolve_class_from_name(referer,ref->referermethod,
1906 ref->methodref->p.classref->name,mode,true,true,&container))
1908 /* the class reference could not be resolved */
1909 return false; /* exception */
1912 return true; /* be lazy */
1915 assert(container->state & CLASS_LINKED);
1917 /* now we must find the declaration of the method in `container`
1918 * or one of its superclasses */
1920 if (container->flags & ACC_INTERFACE) {
1921 mi = class_resolveinterfacemethod(container,
1922 ref->methodref->name,
1923 ref->methodref->descriptor,
1927 mi = class_resolveclassmethod(container,
1928 ref->methodref->name,
1929 ref->methodref->descriptor,
1934 if (mode == resolveLazy) {
1935 /* The method does not exist. But since we were called lazily, */
1936 /* this error must not be reported now. (It will be reported */
1937 /* if eager resolving of this method is ever tried.) */
1939 *exceptionptr = NULL;
1940 return true; /* be lazy */
1943 return false; /* exception */ /* XXX set exceptionptr? */
1946 /* { the method reference has been resolved } */
1948 if (ref->flags & RESOLVE_SPECIAL) {
1949 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
1951 return false; /* exception */
1954 /* have the method params already been parsed? no, do it. */
1956 if (!mi->parseddesc->params)
1957 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1960 /* cache the resolution */
1962 ref->methodref->p.method = mi;
1964 resolved_the_method:
1966 #ifdef ENABLE_VERIFIER
1969 checkresult = resolve_method_verifier_checks(
1973 (ref->flags & RESOLVE_STATIC));
1975 if (checkresult != resolveSucceeded)
1976 return (bool) checkresult;
1978 /* impose loading constraints on params and return type */
1980 if (!resolve_method_loading_constraints(referer, mi))
1983 declarer = mi->class;
1985 assert(referer->state & CLASS_LINKED);
1987 /* for non-static methods we have to check the constraints on the */
1990 if (!(ref->flags & RESOLVE_STATIC)) {
1991 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1992 &(ref->instancetypes),
1993 CLASSREF_OR_CLASSINFO(container),
1995 resolveLinkageError);
1996 if (checkresult != resolveSucceeded)
1997 return (bool) checkresult;
2004 /* check subtype constraints for TYPE_ADR parameters */
2006 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2007 paramtypes = mi->parseddesc->paramtypes;
2009 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2010 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2011 if (ref->paramconstraints) {
2012 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2013 ref->paramconstraints + i,
2014 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2016 resolveLinkageError);
2017 if (checkresult != resolveSucceeded)
2018 return (bool) checkresult;
2023 /* check protected access */
2025 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2027 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2028 &(ref->instancetypes),
2029 CLASSREF_OR_CLASSINFO(referer),
2031 resolveIllegalAccessError);
2032 if (checkresult != resolveSucceeded)
2033 return (bool) checkresult;
2036 #endif /* ENABLE_VERIFIER */
2043 /* resolve_method_eager ********************************************************
2045 Resolve an unresolved method reference eagerly.
2048 ref..............struct containing the reference
2051 methodinfo * to the method, or
2052 NULL if an exception has been thrown
2054 *******************************************************************************/
2056 methodinfo * resolve_method_eager(unresolved_method *ref)
2060 if (!resolve_method(ref,resolveEager,&mi))
2066 /******************************************************************************/
2067 /* CREATING THE DATA STRUCTURES */
2068 /******************************************************************************/
2070 #ifdef ENABLE_VERIFIER
2071 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2072 methodinfo *refmethod,
2073 unresolved_subtype_set *stset,
2075 utf *declaredclassname)
2083 #ifdef RESOLVE_VERBOSE
2084 printf("unresolved_subtype_set_from_typeinfo\n");
2085 #ifdef TYPEINFO_DEBUG
2086 typeinfo_print(stdout,tinfo,4);
2088 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2092 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2093 exceptions_throw_verifyerror(refmethod,
2094 "Invalid use of returnAddress");
2098 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2099 exceptions_throw_verifyerror(refmethod,
2100 "Invalid use of uninitialized object");
2104 /* the nulltype is always assignable */
2105 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2108 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2109 if (declaredclassname == utf_java_lang_Object
2110 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2115 if (tinfo->merged) {
2116 count = tinfo->merged->count;
2117 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2118 for (i=0; i<count; ++i) {
2119 classref_or_classinfo c = tinfo->merged->list[i];
2120 if (tinfo->dimension > 0) {
2121 /* a merge of array types */
2122 /* the merged list contains the possible _element_ types, */
2123 /* so we have to create array types with these elements. */
2124 if (IS_CLASSREF(c)) {
2125 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2128 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2131 stset->subtyperefs[i] = c;
2133 stset->subtyperefs[count].any = NULL; /* terminate */
2136 if ((IS_CLASSREF(tinfo->typeclass)
2137 ? tinfo->typeclass.ref->name
2138 : tinfo->typeclass.cls->name) == declaredclassname)
2140 /* the class names are the same */
2141 /* equality is guaranteed by the loading constraints */
2145 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2146 stset->subtyperefs[0] = tinfo->typeclass;
2147 stset->subtyperefs[1].any = NULL; /* terminate */
2154 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2157 #endif /* ENABLE_VERIFIER */
2159 /* create_unresolved_class *****************************************************
2161 Create an unresolved_class struct for the given class reference
2164 refmethod........the method triggering the resolution (if any)
2165 classref.........the class reference
2166 valuetype........value type to check against the resolved class
2167 may be NULL, if no typeinfo is available
2170 a pointer to a new unresolved_class struct, or
2171 NULL if an exception has been thrown
2173 *******************************************************************************/
2175 #ifdef ENABLE_VERIFIER
2176 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2177 constant_classref *classref,
2178 typeinfo *valuetype)
2180 unresolved_class *ref;
2182 #ifdef RESOLVE_VERBOSE
2183 printf("create_unresolved_class\n");
2184 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2186 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2187 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2189 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2192 ref = NEW(unresolved_class);
2193 ref->classref = classref;
2194 ref->referermethod = refmethod;
2197 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2198 &(ref->subtypeconstraints),valuetype,classref->name))
2202 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2207 #endif /* ENABLE_VERIFIER */
2209 /* resolve_create_unresolved_field *********************************************
2211 Create an unresolved_field struct for the given field access instruction
2214 referer..........the class containing the reference
2215 refmethod........the method triggering the resolution (if any)
2216 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2219 a pointer to a new unresolved_field struct, or
2220 NULL if an exception has been thrown
2222 *******************************************************************************/
2224 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2225 methodinfo *refmethod,
2228 unresolved_field *ref;
2229 constant_FMIref *fieldref = NULL;
2231 #ifdef RESOLVE_VERBOSE
2232 printf("create_unresolved_field\n");
2233 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2234 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2235 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2238 ref = NEW(unresolved_field);
2240 ref->referermethod = refmethod;
2241 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2243 switch (iptr->opc) {
2245 ref->flags |= RESOLVE_PUTFIELD;
2248 case ICMD_PUTFIELDCONST:
2249 ref->flags |= RESOLVE_PUTFIELD;
2252 case ICMD_PUTSTATIC:
2253 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2256 case ICMD_PUTSTATICCONST:
2257 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2263 case ICMD_GETSTATIC:
2264 ref->flags |= RESOLVE_STATIC;
2267 #if !defined(NDEBUG)
2273 fieldref = iptr->sx.s23.s3.fmiref;
2277 #ifdef RESOLVE_VERBOSE
2278 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2279 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2280 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2281 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2283 /*printf(" opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2286 ref->fieldref = fieldref;
2291 /* resolve_constrain_unresolved_field ******************************************
2293 Record subtype constraints for a field access.
2296 ref..............the unresolved_field structure of the access
2297 referer..........the class containing the reference
2298 refmethod........the method triggering the resolution (if any)
2299 instanceti.......instance typeinfo, if available
2300 valueti..........value typeinfo, if available
2303 true.............everything ok
2304 false............an exception has been thrown
2306 *******************************************************************************/
2308 #if defined(ENABLE_VERIFIER)
2309 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2311 methodinfo *refmethod,
2312 typeinfo *instanceti,
2315 constant_FMIref *fieldref;
2322 fieldref = ref->fieldref;
2325 #ifdef RESOLVE_VERBOSE
2326 printf("constrain_unresolved_field\n");
2327 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2328 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2329 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2330 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2331 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2332 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2333 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2335 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2338 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2339 fd = fieldref->parseddesc.fd;
2342 /* record subtype constraints for the instance type, if any */
2346 /* The instanceslot must contain a reference to a non-array type */
2347 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2348 exceptions_throw_verifyerror(refmethod,
2349 "illegal instruction: field access on non-reference");
2352 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2353 exceptions_throw_verifyerror(refmethod,
2354 "illegal instruction: field access on array");
2358 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2359 TYPEINFO_IS_NEWOBJECT(*instanceti))
2361 /* The instruction writes a field in an uninitialized object. */
2362 /* This is only allowed when a field of an uninitialized 'this' object is */
2363 /* written inside an initialization method */
2365 classinfo *initclass;
2366 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2369 exceptions_throw_verifyerror(refmethod,
2370 "accessing field of uninitialized object");
2373 /* XXX check that class of field == refmethod->class */
2374 initclass = refmethod->class; /* XXX classrefs */
2375 assert(initclass->state & CLASS_LOADED);
2376 assert(initclass->state & CLASS_LINKED);
2378 typeinfo_init_classinfo(&tinfo, initclass);
2382 insttip = instanceti;
2384 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2385 &(ref->instancetypes), insttip,
2386 FIELDREF_CLASSNAME(fieldref)))
2390 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2393 /* record subtype constraints for the value type, if any */
2395 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2397 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2398 &(ref->valueconstraints), valueti,
2399 fieldref->parseddesc.fd->classref->name))
2403 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2408 #endif /* ENABLE_VERIFIER */
2410 /* resolve_create_unresolved_method ********************************************
2412 Create an unresolved_method struct for the given method invocation
2415 referer..........the class containing the reference
2416 refmethod........the method triggering the resolution (if any)
2417 iptr.............the INVOKE* instruction
2420 a pointer to a new unresolved_method struct, or
2421 NULL if an exception has been thrown
2423 *******************************************************************************/
2425 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2426 methodinfo *refmethod,
2427 constant_FMIref *methodref,
2431 unresolved_method *ref;
2435 #ifdef RESOLVE_VERBOSE
2436 printf("create_unresolved_method\n");
2437 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2438 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2439 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2440 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2441 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2444 /* allocate params if necessary */
2445 if (!methodref->parseddesc.md->params)
2446 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2447 (invokestatic) ? ACC_STATIC : ACC_NONE))
2450 /* create the data structure */
2451 ref = NEW(unresolved_method);
2452 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2453 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2454 ref->referermethod = refmethod;
2455 ref->methodref = methodref;
2456 ref->paramconstraints = NULL;
2457 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2462 /* constrain_unresolved_method *********************************************
2464 Record subtype constraints for the arguments of a method call.
2467 ref..............the unresolved_method structure of the call
2468 referer..........the class containing the reference
2469 refmethod........the method triggering the resolution (if any)
2470 iptr.............the INVOKE* instruction
2473 true.............everything ok
2474 false............an exception has been thrown
2476 *******************************************************************************/
2478 #ifdef ENABLE_VERIFIER
2479 bool constrain_unresolved_method(jitdata *jd,
2480 unresolved_method *ref,
2481 classinfo *referer, methodinfo *refmethod,
2484 constant_FMIref *methodref;
2485 constant_classref *instanceref;
2486 varinfo *instanceslot = NULL;
2495 methodref = ref->methodref;
2497 md = methodref->parseddesc.md;
2499 assert(md->params != NULL);
2501 /* XXX clean this up */
2502 instanceref = IS_FMIREF_RESOLVED(methodref)
2503 ? class_get_self_classref(methodref->p.method->class)
2504 : methodref->p.classref;
2506 #ifdef RESOLVE_VERBOSE
2507 printf("constrain_unresolved_method\n");
2508 printf(" referer: "); class_println(referer);
2509 printf(" rmethod: "); method_println(refmethod);
2510 printf(" mref : "); method_methodref_println(methodref);
2511 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2514 if ((ref->flags & RESOLVE_STATIC) == 0) {
2515 /* find the instance slot under all the parameter slots on the stack */
2516 instanceslot = VAR(iptr->sx.s23.s2.args[0]);
2523 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
2525 /* record subtype constraints for the instance type, if any */
2529 assert(instanceslot->type == TYPE_ADR);
2531 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
2532 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2533 { /* XXX clean up */
2534 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2535 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2536 : CLASSREF_OR_CLASSINFO(refmethod->class);
2538 if (!typeinfo_init_class(tip,initclass))
2542 tip = &(instanceslot->typeinfo);
2544 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2545 &(ref->instancetypes),tip,instanceref->name))
2549 /* record subtype constraints for the parameter types, if any */
2550 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2551 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2552 type = md->paramtypes[i+instancecount].type;
2555 assert(type == param->type);
2557 if (type == TYPE_ADR) {
2558 if (!ref->paramconstraints) {
2559 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2560 for (j=md->paramcount-1-instancecount; j>i; --j)
2561 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2563 assert(ref->paramconstraints);
2564 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2565 ref->paramconstraints + i,&(param->typeinfo),
2566 md->paramtypes[i+instancecount].classref->name))
2570 if (ref->paramconstraints)
2571 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2577 #endif /* ENABLE_VERIFIER */
2579 /******************************************************************************/
2580 /* FREEING MEMORY */
2581 /******************************************************************************/
2583 #ifdef ENABLE_VERIFIER
2584 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2587 classref_or_classinfo *p = list;
2589 /* this is silly. we *only* need to count the elements for MFREE */
2592 MFREE(list,classref_or_classinfo,(p - list));
2595 #endif /* ENABLE_VERIFIER */
2597 /* unresolved_class_free *******************************************************
2599 Free the memory used by an unresolved_class
2602 ref..............the unresolved_class
2604 *******************************************************************************/
2606 void unresolved_class_free(unresolved_class *ref)
2610 #ifdef ENABLE_VERIFIER
2611 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2613 FREE(ref,unresolved_class);
2616 /* unresolved_field_free *******************************************************
2618 Free the memory used by an unresolved_field
2621 ref..............the unresolved_field
2623 *******************************************************************************/
2625 void unresolved_field_free(unresolved_field *ref)
2629 #ifdef ENABLE_VERIFIER
2630 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2631 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2633 FREE(ref,unresolved_field);
2636 /* unresolved_method_free ******************************************************
2638 Free the memory used by an unresolved_method
2641 ref..............the unresolved_method
2643 *******************************************************************************/
2645 void unresolved_method_free(unresolved_method *ref)
2649 #ifdef ENABLE_VERIFIER
2650 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2651 if (ref->paramconstraints) {
2653 int count = ref->methodref->parseddesc.md->paramcount;
2655 for (i=0; i<count; ++i)
2656 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2657 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2660 FREE(ref,unresolved_method);
2663 /******************************************************************************/
2665 /******************************************************************************/
2667 #if !defined(NDEBUG)
2669 /* unresolved_subtype_set_debug_dump *******************************************
2671 Print debug info for unresolved_subtype_set to stream
2674 stset............the unresolved_subtype_set
2675 file.............the stream
2677 *******************************************************************************/
2679 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2681 classref_or_classinfo *p;
2683 if (SUBTYPESET_IS_EMPTY(*stset)) {
2684 fprintf(file," (empty)\n");
2687 p = stset->subtyperefs;
2688 for (;p->any; ++p) {
2689 if (IS_CLASSREF(*p)) {
2690 fprintf(file," ref: ");
2691 utf_fprint_printable_ascii(file,p->ref->name);
2694 fprintf(file," cls: ");
2695 utf_fprint_printable_ascii(file,p->cls->name);
2702 /* unresolved_class_debug_dump *************************************************
2704 Print debug info for unresolved_class to stream
2707 ref..............the unresolved_class
2708 file.............the stream
2710 *******************************************************************************/
2712 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2714 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2716 fprintf(file," referer : ");
2717 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2718 fprintf(file," refmethod : ");
2719 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2720 fprintf(file," refmethodd: ");
2721 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2722 fprintf(file," classname : ");
2723 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2724 fprintf(file," subtypeconstraints:\n");
2725 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2729 /* unresolved_field_debug_dump *************************************************
2731 Print debug info for unresolved_field to stream
2734 ref..............the unresolved_field
2735 file.............the stream
2737 *******************************************************************************/
2739 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2741 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2743 fprintf(file," referer : ");
2744 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2745 fprintf(file," refmethod : ");
2746 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2747 fprintf(file," refmethodd: ");
2748 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2749 fprintf(file," classname : ");
2750 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
2751 fprintf(file," name : ");
2752 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
2753 fprintf(file," descriptor: ");
2754 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
2755 fprintf(file," parseddesc: ");
2756 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2757 fprintf(file," flags : %04x\n",ref->flags);
2758 fprintf(file," instancetypes:\n");
2759 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2760 fprintf(file," valueconstraints:\n");
2761 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2765 /* unresolved_method_debug_dump ************************************************
2767 Print debug info for unresolved_method to stream
2770 ref..............the unresolved_method
2771 file.............the stream
2773 *******************************************************************************/
2775 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2779 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2781 fprintf(file," referer : ");
2782 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2783 fprintf(file," refmethod : ");
2784 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2785 fprintf(file," refmethodd: ");
2786 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2787 fprintf(file," classname : ");
2788 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
2789 fprintf(file," name : ");
2790 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
2791 fprintf(file," descriptor: ");
2792 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
2793 fprintf(file," parseddesc: ");
2794 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2795 fprintf(file," flags : %04x\n",ref->flags);
2796 fprintf(file," instancetypes:\n");
2797 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2798 fprintf(file," paramconstraints:\n");
2799 if (ref->paramconstraints) {
2800 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2801 fprintf(file," param %d:\n",i);
2802 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2806 fprintf(file," (empty)\n");
2810 #endif /* !defined(NDEBUG) */
2813 * These are local overrides for various environment variables in Emacs.
2814 * Please do not remove this and leave it at the end of the file, where
2815 * Emacs will automagically detect them.
2816 * ---------------------------------------------------------------------
2819 * indent-tabs-mode: t
2823 * vim:noexpandtab:sw=4:ts=4: