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 5725 2006-10-09 22:19:22Z 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 container........the class where the method was found
1462 mi...............the methodinfo of the resolved method
1463 invokestatic.....true if the method is invoked by INVOKESTATIC
1464 iptr.............the invoke instruction, or NULL
1467 resolveSucceeded....everything ok
1468 resolveDeferred.....tests could not be done, have been deferred
1469 resolveFailed.......exception has been thrown
1471 *******************************************************************************/
1473 #if defined(ENABLE_VERIFIER)
1474 resolve_result_t resolve_method_verifier_checks(jitdata *jd,
1475 methodinfo *refmethod,
1476 constant_FMIref *methodref,
1477 classinfo *container,
1483 classinfo *declarer;
1485 resolve_result_t result;
1487 typedesc *paramtypes;
1489 varinfo *instanceslot = NULL;
1500 #ifdef RESOLVE_VERBOSE
1501 printf("resolve_method_verifier_checks\n");
1502 printf(" flags: %02x\n",mi->flags);
1505 /* get the classinfos and the method descriptor */
1507 referer = refmethod->class;
1510 declarer = mi->class;
1512 assert(referer->state & CLASS_LINKED);
1514 md = methodref->parseddesc.md;
1518 instancecount = (invokestatic) ? 0 : 1;
1522 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1523 /* a static method is accessed via an instance, or vice versa */
1525 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1526 (mi->flags & ACC_STATIC) ? "static method called via instance"
1527 : "instance method called without instance");
1528 return resolveFailed;
1531 /* check access rights */
1533 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1537 /* XXX clean this up. this should be in exceptions.c */
1538 msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
1539 utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
1540 message = MNEW(char, msglen);
1541 strcpy(message, "method is not accessible (");
1542 utf_cat_classname(message, declarer->name);
1543 strcat(message, ".");
1544 utf_cat(message, mi->name);
1545 utf_cat(message, mi->descriptor);
1546 strcat(message," from ");
1547 utf_cat_classname(message, referer->name);
1548 strcat(message,")");
1549 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1550 MFREE(message, char, msglen);
1551 return resolveFailed; /* exception */
1555 /* for non-static methods we have to check the constraints on the */
1560 if (!invokestatic) {
1561 instanceslot = VAR(iptr->sx.s23.s2.args[0]);
1564 assert((instanceslot && instancecount == 1) || invokestatic);
1566 /* record subtype constraints for the instance type, if any */
1570 assert(instanceslot->type == TYPE_ADR);
1572 if (invokespecial &&
1573 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1574 { /* XXX clean up */
1575 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1576 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1577 : CLASSREF_OR_CLASSINFO(refmethod->class);
1579 if (!typeinfo_init_class(tip,initclass))
1583 tip = &(instanceslot->typeinfo);
1586 result = resolve_lazy_subtype_checks(refmethod,
1588 CLASSREF_OR_CLASSINFO(container),
1589 resolveLinkageError);
1590 if (result != resolveSucceeded)
1593 /* check protected access */
1595 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1597 result = resolve_lazy_subtype_checks(refmethod,
1599 CLASSREF_OR_CLASSINFO(referer),
1600 resolveIllegalAccessError);
1601 if (result != resolveSucceeded)
1607 /* check subtype constraints for TYPE_ADR parameters */
1609 assert(md->paramcount == methodref->parseddesc.md->paramcount);
1610 paramtypes = md->paramtypes;
1612 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1613 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1614 type = md->paramtypes[i+instancecount].type;
1617 assert(type == param->type);
1619 if (type == TYPE_ADR) {
1620 result = resolve_lazy_subtype_checks(refmethod,
1622 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1623 resolveLinkageError);
1624 if (result != resolveSucceeded)
1633 return resolveSucceeded;
1635 #endif /* defined(ENABLE_VERIFIER) */
1638 /* resolve_method_loading_constraints ******************************************
1640 Impose loading constraints on the parameters and return type of the
1644 referer..........the class refering to the method
1645 mi...............the method
1648 true................everything ok
1649 false...............an exception has been thrown
1651 *******************************************************************************/
1653 #if defined(ENABLE_VERIFIER)
1654 bool resolve_method_loading_constraints(classinfo *referer,
1658 typedesc *paramtypes;
1663 /* impose loading constraints on parameters (including instance) */
1665 md = mi->parseddesc;
1666 paramtypes = md->paramtypes;
1667 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1669 for (i = 0; i < md->paramcount; i++) {
1670 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1671 if (i < instancecount) {
1672 /* The type of the 'this' pointer is the class containing */
1673 /* the method definition. Since container is the same as, */
1674 /* or a subclass of declarer, we also constrain declarer */
1675 /* by transitivity of loading constraints. */
1676 name = mi->class->name;
1679 name = paramtypes[i].classref->name;
1682 /* The caller (referer) and the callee (container) must agree */
1683 /* on the types of the parameters. */
1684 if (!classcache_add_constraint(referer->classloader,
1685 mi->class->classloader, name))
1686 return false; /* exception */
1690 /* impose loading constraint onto return type */
1692 if (md->returntype.type == TYPE_ADR) {
1693 /* The caller (referer) and the callee (container) must agree */
1694 /* on the return type. */
1695 if (!classcache_add_constraint(referer->classloader,
1696 mi->class->classloader,
1697 md->returntype.classref->name))
1698 return false; /* exception */
1705 #endif /* defined(ENABLE_VERIFIER) */
1708 /* resolve_method_lazy *********************************************************
1710 Resolve an unresolved method reference lazily
1712 NOTE: This function does NOT do any verification checks. In case of a
1713 successful resolution, you must call resolve_method_verifier_checks
1714 in order to perform the necessary checks!
1717 refmethod........the referer method
1718 methodref........the method reference
1719 invokespecial....true if this is an INVOKESPECIAL instruction
1722 resolveSucceeded.....the reference has been resolved
1723 resolveDeferred......the resolving could not be performed lazily
1724 resolveFailed........resolving failed, an exception has been thrown.
1726 *******************************************************************************/
1728 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1729 constant_FMIref *methodref,
1733 classinfo *container;
1738 #ifdef RESOLVE_VERBOSE
1739 printf("resolve_method_lazy\n");
1742 /* the class containing the reference */
1744 referer = refmethod->class;
1747 /* check if the method itself is already resolved */
1749 if (IS_FMIREF_RESOLVED(methodref))
1750 return resolveSucceeded;
1752 /* first we must resolve the class containg the method */
1754 if (!resolve_class_from_name(referer, refmethod,
1755 methodref->p.classref->name, resolveLazy, true, true, &container))
1757 /* the class reference could not be resolved */
1758 return resolveFailed; /* exception */
1761 return resolveDeferred; /* be lazy */
1763 assert(container->state & CLASS_LINKED);
1765 /* now we must find the declaration of the method in `container`
1766 * or one of its superclasses */
1768 if (container->flags & ACC_INTERFACE) {
1769 mi = class_resolveinterfacemethod(container,
1771 methodref->descriptor,
1775 mi = class_resolveclassmethod(container,
1777 methodref->descriptor,
1782 /* The method does not exist. But since we were called lazily, */
1783 /* this error must not be reported now. (It will be reported */
1784 /* if eager resolving of this method is ever tried.) */
1786 *exceptionptr = NULL;
1787 return resolveDeferred; /* be lazy */
1790 if (invokespecial) {
1791 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1793 return resolveFailed; /* exception */
1796 /* have the method params already been parsed? no, do it. */
1798 if (!mi->parseddesc->params)
1799 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1800 return resolveFailed;
1802 /* cache the result of the resolution */
1804 methodref->p.method = mi;
1808 return resolveSucceeded;
1811 /* resolve_method **************************************************************
1813 Resolve an unresolved method reference
1816 ref..............struct containing the reference
1817 mode.............mode of resolution:
1818 resolveLazy...only resolve if it does not
1819 require loading classes
1820 resolveEager..load classes if necessary
1823 *result..........set to the result of resolution, or to NULL if
1824 the reference has not been resolved
1825 In the case of an exception, *result is
1826 guaranteed to be set to NULL.
1829 true.............everything ok
1830 (*result may still be NULL for resolveLazy)
1831 false............an exception has been thrown
1833 *******************************************************************************/
1835 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1838 classinfo *container;
1839 classinfo *declarer;
1841 typedesc *paramtypes;
1844 resolve_result_t checkresult;
1848 assert(mode == resolveLazy || mode == resolveEager);
1850 #ifdef RESOLVE_VERBOSE
1851 unresolved_method_debug_dump(ref,stdout);
1856 /* the class containing the reference */
1858 referer = ref->referermethod->class;
1861 /* check if the method itself is already resolved */
1863 if (IS_FMIREF_RESOLVED(ref->methodref)) {
1864 mi = ref->methodref->p.method;
1865 container = mi->class;
1866 goto resolved_the_method;
1869 /* first we must resolve the class containing the method */
1871 if (!resolve_class_from_name(referer,ref->referermethod,
1872 ref->methodref->p.classref->name,mode,true,true,&container))
1874 /* the class reference could not be resolved */
1875 return false; /* exception */
1878 return true; /* be lazy */
1881 assert(container->state & CLASS_LINKED);
1883 /* now we must find the declaration of the method in `container`
1884 * or one of its superclasses */
1886 if (container->flags & ACC_INTERFACE) {
1887 mi = class_resolveinterfacemethod(container,
1888 ref->methodref->name,
1889 ref->methodref->descriptor,
1893 mi = class_resolveclassmethod(container,
1894 ref->methodref->name,
1895 ref->methodref->descriptor,
1900 if (mode == resolveLazy) {
1901 /* The method does not exist. But since we were called lazily, */
1902 /* this error must not be reported now. (It will be reported */
1903 /* if eager resolving of this method is ever tried.) */
1905 *exceptionptr = NULL;
1906 return true; /* be lazy */
1909 return false; /* exception */ /* XXX set exceptionptr? */
1912 /* { the method reference has been resolved } */
1914 if (ref->flags & RESOLVE_SPECIAL) {
1915 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
1917 return false; /* exception */
1920 /* have the method params already been parsed? no, do it. */
1922 if (!mi->parseddesc->params)
1923 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1926 /* cache the resolution */
1928 ref->methodref->p.method = mi;
1930 resolved_the_method:
1932 #ifdef ENABLE_VERIFIER
1933 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1934 /* that no missing parts of an instruction will be accessed. */
1937 checkresult = resolve_method_verifier_checks(NULL,
1942 (ref->flags & RESOLVE_STATIC),
1943 (ref->flags & RESOLVE_SPECIAL),
1946 if (checkresult != resolveSucceeded)
1947 return (bool) checkresult;
1949 /* impose loading constraints on params and return type */
1951 if (!resolve_method_loading_constraints(referer, mi))
1954 declarer = mi->class;
1956 assert(referer->state & CLASS_LINKED);
1958 /* for non-static methods we have to check the constraints on the */
1961 if (!(ref->flags & RESOLVE_STATIC)) {
1962 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1963 &(ref->instancetypes),
1964 CLASSREF_OR_CLASSINFO(container),
1966 resolveLinkageError);
1967 if (checkresult != resolveSucceeded)
1968 return (bool) checkresult;
1975 /* check subtype constraints for TYPE_ADR parameters */
1977 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
1978 paramtypes = mi->parseddesc->paramtypes;
1980 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
1981 if (paramtypes[i+instancecount].type == TYPE_ADR) {
1982 if (ref->paramconstraints) {
1983 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1984 ref->paramconstraints + i,
1985 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1987 resolveLinkageError);
1988 if (checkresult != resolveSucceeded)
1989 return (bool) checkresult;
1994 /* check protected access */
1996 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1998 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1999 &(ref->instancetypes),
2000 CLASSREF_OR_CLASSINFO(referer),
2002 resolveIllegalAccessError);
2003 if (checkresult != resolveSucceeded)
2004 return (bool) checkresult;
2007 #endif /* ENABLE_VERIFIER */
2014 /* resolve_method_eager ********************************************************
2016 Resolve an unresolved method reference eagerly.
2019 ref..............struct containing the reference
2022 methodinfo * to the method, or
2023 NULL if an exception has been thrown
2025 *******************************************************************************/
2027 methodinfo * resolve_method_eager(unresolved_method *ref)
2031 if (!resolve_method(ref,resolveEager,&mi))
2037 /******************************************************************************/
2038 /* CREATING THE DATA STRUCTURES */
2039 /******************************************************************************/
2041 #ifdef ENABLE_VERIFIER
2042 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2043 methodinfo *refmethod,
2044 unresolved_subtype_set *stset,
2046 utf *declaredclassname)
2054 #ifdef RESOLVE_VERBOSE
2055 printf("unresolved_subtype_set_from_typeinfo\n");
2056 #ifdef TYPEINFO_DEBUG
2057 typeinfo_print(stdout,tinfo,4);
2059 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2063 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2064 exceptions_throw_verifyerror(refmethod,
2065 "Invalid use of returnAddress");
2069 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2070 exceptions_throw_verifyerror(refmethod,
2071 "Invalid use of uninitialized object");
2075 /* the nulltype is always assignable */
2076 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2079 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2080 if (declaredclassname == utf_java_lang_Object
2081 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2086 if (tinfo->merged) {
2087 count = tinfo->merged->count;
2088 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2089 for (i=0; i<count; ++i) {
2090 classref_or_classinfo c = tinfo->merged->list[i];
2091 if (tinfo->dimension > 0) {
2092 /* a merge of array types */
2093 /* the merged list contains the possible _element_ types, */
2094 /* so we have to create array types with these elements. */
2095 if (IS_CLASSREF(c)) {
2096 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2099 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2102 stset->subtyperefs[i] = c;
2104 stset->subtyperefs[count].any = NULL; /* terminate */
2107 if ((IS_CLASSREF(tinfo->typeclass)
2108 ? tinfo->typeclass.ref->name
2109 : tinfo->typeclass.cls->name) == declaredclassname)
2111 /* the class names are the same */
2112 /* equality is guaranteed by the loading constraints */
2116 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2117 stset->subtyperefs[0] = tinfo->typeclass;
2118 stset->subtyperefs[1].any = NULL; /* terminate */
2125 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2128 #endif /* ENABLE_VERIFIER */
2130 /* create_unresolved_class *****************************************************
2132 Create an unresolved_class struct for the given class reference
2135 refmethod........the method triggering the resolution (if any)
2136 classref.........the class reference
2137 valuetype........value type to check against the resolved class
2138 may be NULL, if no typeinfo is available
2141 a pointer to a new unresolved_class struct, or
2142 NULL if an exception has been thrown
2144 *******************************************************************************/
2146 #ifdef ENABLE_VERIFIER
2147 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2148 constant_classref *classref,
2149 typeinfo *valuetype)
2151 unresolved_class *ref;
2153 #ifdef RESOLVE_VERBOSE
2154 printf("create_unresolved_class\n");
2155 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2157 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2158 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2160 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2163 ref = NEW(unresolved_class);
2164 ref->classref = classref;
2165 ref->referermethod = refmethod;
2168 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2169 &(ref->subtypeconstraints),valuetype,classref->name))
2173 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2178 #endif /* ENABLE_VERIFIER */
2180 /* resolve_create_unresolved_field *********************************************
2182 Create an unresolved_field struct for the given field access instruction
2185 referer..........the class containing the reference
2186 refmethod........the method triggering the resolution (if any)
2187 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2190 a pointer to a new unresolved_field struct, or
2191 NULL if an exception has been thrown
2193 *******************************************************************************/
2195 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2196 methodinfo *refmethod,
2199 unresolved_field *ref;
2200 constant_FMIref *fieldref = NULL;
2202 #ifdef RESOLVE_VERBOSE
2203 printf("create_unresolved_field\n");
2204 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2205 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2206 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2209 ref = NEW(unresolved_field);
2211 ref->referermethod = refmethod;
2212 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2214 switch (iptr->opc) {
2216 ref->flags |= RESOLVE_PUTFIELD;
2219 case ICMD_PUTFIELDCONST:
2220 ref->flags |= RESOLVE_PUTFIELD;
2223 case ICMD_PUTSTATIC:
2224 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2227 case ICMD_PUTSTATICCONST:
2228 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2234 case ICMD_GETSTATIC:
2235 ref->flags |= RESOLVE_STATIC;
2238 #if !defined(NDEBUG)
2244 fieldref = iptr->sx.s23.s3.fmiref;
2248 #ifdef RESOLVE_VERBOSE
2249 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2250 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2251 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2252 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2254 /*printf(" opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2257 ref->fieldref = fieldref;
2262 /* resolve_constrain_unresolved_field ******************************************
2264 Record subtype constraints for a field access.
2267 ref..............the unresolved_field structure of the access
2268 referer..........the class containing the reference
2269 refmethod........the method triggering the resolution (if any)
2270 instanceti.......instance typeinfo, if available
2271 valueti..........value typeinfo, if available
2274 true.............everything ok
2275 false............an exception has been thrown
2277 *******************************************************************************/
2279 #if defined(ENABLE_VERIFIER)
2280 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2282 methodinfo *refmethod,
2283 typeinfo *instanceti,
2286 constant_FMIref *fieldref;
2293 fieldref = ref->fieldref;
2296 #ifdef RESOLVE_VERBOSE
2297 printf("constrain_unresolved_field\n");
2298 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2299 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2300 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2301 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2302 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2303 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2304 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2306 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2309 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2310 fd = fieldref->parseddesc.fd;
2313 /* record subtype constraints for the instance type, if any */
2317 /* The instanceslot must contain a reference to a non-array type */
2318 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2319 exceptions_throw_verifyerror(refmethod,
2320 "illegal instruction: field access on non-reference");
2323 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2324 exceptions_throw_verifyerror(refmethod,
2325 "illegal instruction: field access on array");
2329 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2330 TYPEINFO_IS_NEWOBJECT(*instanceti))
2332 /* The instruction writes a field in an uninitialized object. */
2333 /* This is only allowed when a field of an uninitialized 'this' object is */
2334 /* written inside an initialization method */
2336 classinfo *initclass;
2337 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2340 exceptions_throw_verifyerror(refmethod,
2341 "accessing field of uninitialized object");
2344 /* XXX check that class of field == refmethod->class */
2345 initclass = refmethod->class; /* XXX classrefs */
2346 assert(initclass->state & CLASS_LOADED);
2347 assert(initclass->state & CLASS_LINKED);
2349 typeinfo_init_classinfo(&tinfo, initclass);
2353 insttip = instanceti;
2355 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2356 &(ref->instancetypes), insttip,
2357 FIELDREF_CLASSNAME(fieldref)))
2361 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2364 /* record subtype constraints for the value type, if any */
2366 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2368 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2369 &(ref->valueconstraints), valueti,
2370 fieldref->parseddesc.fd->classref->name))
2374 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2379 #endif /* ENABLE_VERIFIER */
2381 /* resolve_create_unresolved_method ********************************************
2383 Create an unresolved_method struct for the given method invocation
2386 referer..........the class containing the reference
2387 refmethod........the method triggering the resolution (if any)
2388 iptr.............the INVOKE* instruction
2391 a pointer to a new unresolved_method struct, or
2392 NULL if an exception has been thrown
2394 *******************************************************************************/
2396 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2397 methodinfo *refmethod,
2398 constant_FMIref *methodref,
2402 unresolved_method *ref;
2406 #ifdef RESOLVE_VERBOSE
2407 printf("create_unresolved_method\n");
2408 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2409 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2410 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2411 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2412 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2415 /* allocate params if necessary */
2416 if (!methodref->parseddesc.md->params)
2417 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2418 (invokestatic) ? ACC_STATIC : ACC_NONE))
2421 /* create the data structure */
2422 ref = NEW(unresolved_method);
2423 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2424 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2425 ref->referermethod = refmethod;
2426 ref->methodref = methodref;
2427 ref->paramconstraints = NULL;
2428 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2433 /* constrain_unresolved_method *********************************************
2435 Record subtype constraints for the arguments of a method call.
2438 ref..............the unresolved_method structure of the call
2439 referer..........the class containing the reference
2440 refmethod........the method triggering the resolution (if any)
2441 iptr.............the INVOKE* instruction
2444 true.............everything ok
2445 false............an exception has been thrown
2447 *******************************************************************************/
2449 #ifdef ENABLE_VERIFIER
2450 bool constrain_unresolved_method(jitdata *jd,
2451 unresolved_method *ref,
2452 classinfo *referer, methodinfo *refmethod,
2455 constant_FMIref *methodref;
2456 constant_classref *instanceref;
2457 varinfo *instanceslot = NULL;
2466 methodref = ref->methodref;
2468 md = methodref->parseddesc.md;
2470 assert(md->params != NULL);
2472 /* XXX clean this up */
2473 instanceref = IS_FMIREF_RESOLVED(methodref)
2474 ? class_get_self_classref(methodref->p.method->class)
2475 : methodref->p.classref;
2477 #ifdef RESOLVE_VERBOSE
2478 printf("constrain_unresolved_method\n");
2479 printf(" referer: "); class_println(referer);
2480 printf(" rmethod: "); method_println(refmethod);
2481 printf(" mref : "); method_methodref_println(methodref);
2482 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2485 if ((ref->flags & RESOLVE_STATIC) == 0) {
2486 /* find the instance slot under all the parameter slots on the stack */
2487 instanceslot = VAR(iptr->sx.s23.s2.args[0]);
2494 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
2496 /* record subtype constraints for the instance type, if any */
2500 assert(instanceslot->type == TYPE_ADR);
2502 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
2503 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2504 { /* XXX clean up */
2505 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2506 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2507 : CLASSREF_OR_CLASSINFO(refmethod->class);
2509 if (!typeinfo_init_class(tip,initclass))
2513 tip = &(instanceslot->typeinfo);
2515 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2516 &(ref->instancetypes),tip,instanceref->name))
2520 /* record subtype constraints for the parameter types, if any */
2521 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2522 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2523 type = md->paramtypes[i+instancecount].type;
2526 assert(type == param->type);
2528 if (type == TYPE_ADR) {
2529 if (!ref->paramconstraints) {
2530 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2531 for (j=md->paramcount-1-instancecount; j>i; --j)
2532 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2534 assert(ref->paramconstraints);
2535 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2536 ref->paramconstraints + i,&(param->typeinfo),
2537 md->paramtypes[i+instancecount].classref->name))
2541 if (ref->paramconstraints)
2542 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2548 #endif /* ENABLE_VERIFIER */
2550 /******************************************************************************/
2551 /* FREEING MEMORY */
2552 /******************************************************************************/
2554 #ifdef ENABLE_VERIFIER
2555 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2558 classref_or_classinfo *p = list;
2560 /* this is silly. we *only* need to count the elements for MFREE */
2563 MFREE(list,classref_or_classinfo,(p - list));
2566 #endif /* ENABLE_VERIFIER */
2568 /* unresolved_class_free *******************************************************
2570 Free the memory used by an unresolved_class
2573 ref..............the unresolved_class
2575 *******************************************************************************/
2577 void unresolved_class_free(unresolved_class *ref)
2581 #ifdef ENABLE_VERIFIER
2582 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2584 FREE(ref,unresolved_class);
2587 /* unresolved_field_free *******************************************************
2589 Free the memory used by an unresolved_field
2592 ref..............the unresolved_field
2594 *******************************************************************************/
2596 void unresolved_field_free(unresolved_field *ref)
2600 #ifdef ENABLE_VERIFIER
2601 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2602 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2604 FREE(ref,unresolved_field);
2607 /* unresolved_method_free ******************************************************
2609 Free the memory used by an unresolved_method
2612 ref..............the unresolved_method
2614 *******************************************************************************/
2616 void unresolved_method_free(unresolved_method *ref)
2620 #ifdef ENABLE_VERIFIER
2621 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2622 if (ref->paramconstraints) {
2624 int count = ref->methodref->parseddesc.md->paramcount;
2626 for (i=0; i<count; ++i)
2627 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2628 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2631 FREE(ref,unresolved_method);
2634 /******************************************************************************/
2636 /******************************************************************************/
2638 #if !defined(NDEBUG)
2640 /* unresolved_subtype_set_debug_dump *******************************************
2642 Print debug info for unresolved_subtype_set to stream
2645 stset............the unresolved_subtype_set
2646 file.............the stream
2648 *******************************************************************************/
2650 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2652 classref_or_classinfo *p;
2654 if (SUBTYPESET_IS_EMPTY(*stset)) {
2655 fprintf(file," (empty)\n");
2658 p = stset->subtyperefs;
2659 for (;p->any; ++p) {
2660 if (IS_CLASSREF(*p)) {
2661 fprintf(file," ref: ");
2662 utf_fprint_printable_ascii(file,p->ref->name);
2665 fprintf(file," cls: ");
2666 utf_fprint_printable_ascii(file,p->cls->name);
2673 /* unresolved_class_debug_dump *************************************************
2675 Print debug info for unresolved_class to stream
2678 ref..............the unresolved_class
2679 file.............the stream
2681 *******************************************************************************/
2683 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2685 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2687 fprintf(file," referer : ");
2688 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2689 fprintf(file," refmethod : ");
2690 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2691 fprintf(file," refmethodd: ");
2692 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2693 fprintf(file," classname : ");
2694 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2695 fprintf(file," subtypeconstraints:\n");
2696 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2700 /* unresolved_field_debug_dump *************************************************
2702 Print debug info for unresolved_field to stream
2705 ref..............the unresolved_field
2706 file.............the stream
2708 *******************************************************************************/
2710 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2712 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2714 fprintf(file," referer : ");
2715 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2716 fprintf(file," refmethod : ");
2717 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2718 fprintf(file," refmethodd: ");
2719 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2720 fprintf(file," classname : ");
2721 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
2722 fprintf(file," name : ");
2723 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
2724 fprintf(file," descriptor: ");
2725 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
2726 fprintf(file," parseddesc: ");
2727 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2728 fprintf(file," flags : %04x\n",ref->flags);
2729 fprintf(file," instancetypes:\n");
2730 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2731 fprintf(file," valueconstraints:\n");
2732 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2736 /* unresolved_method_debug_dump ************************************************
2738 Print debug info for unresolved_method to stream
2741 ref..............the unresolved_method
2742 file.............the stream
2744 *******************************************************************************/
2746 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2750 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2752 fprintf(file," referer : ");
2753 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2754 fprintf(file," refmethod : ");
2755 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2756 fprintf(file," refmethodd: ");
2757 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2758 fprintf(file," classname : ");
2759 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
2760 fprintf(file," name : ");
2761 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
2762 fprintf(file," descriptor: ");
2763 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
2764 fprintf(file," parseddesc: ");
2765 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2766 fprintf(file," flags : %04x\n",ref->flags);
2767 fprintf(file," instancetypes:\n");
2768 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2769 fprintf(file," paramconstraints:\n");
2770 if (ref->paramconstraints) {
2771 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2772 fprintf(file," param %d:\n",i);
2773 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2777 fprintf(file," (empty)\n");
2781 #endif /* !defined(NDEBUG) */
2784 * These are local overrides for various environment variables in Emacs.
2785 * Please do not remove this and leave it at the end of the file, where
2786 * Emacs will automagically detect them.
2787 * ---------------------------------------------------------------------
2790 * indent-tabs-mode: t
2794 * vim:noexpandtab:sw=4:ts=4: