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 5726 2006-10-09 23:06:39Z edwin $
40 #include "mm/memory.h"
41 #include "vm/resolve.h"
42 #include "vm/access.h"
43 #include "vm/classcache.h"
44 #include "vm/descriptor.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/linker.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/stringlocal.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/verify/typeinfo.h"
55 /******************************************************************************/
57 /******************************************************************************/
59 /*#define RESOLVE_VERBOSE*/
61 /******************************************************************************/
62 /* CLASS RESOLUTION */
63 /******************************************************************************/
65 /* resolve_class_from_name *****************************************************
67 Resolve a symbolic class reference
70 referer..........the class containing the reference
71 refmethod........the method from which resolution was triggered
72 (may be NULL if not applicable)
73 classname........class name to resolve
74 mode.............mode of resolution:
75 resolveLazy...only resolve if it does not
76 require loading classes
77 resolveEager..load classes if necessary
78 checkaccess......if true, access rights to the class are checked
79 link.............if true, guarantee that the returned class, if any,
83 *result..........set to result of resolution, or to NULL if
84 the reference has not been resolved
85 In the case of an exception, *result is
86 guaranteed to be set to NULL.
89 true.............everything ok
90 (*result may still be NULL for resolveLazy)
91 false............an exception has been thrown
94 The returned class is *not* guaranteed to be linked!
95 (It is guaranteed to be loaded, though.)
97 *******************************************************************************/
99 bool resolve_class_from_name(classinfo *referer,
100 methodinfo *refmethod,
107 classinfo *cls = NULL;
114 assert(mode == resolveLazy || mode == resolveEager);
118 #ifdef RESOLVE_VERBOSE
119 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;
1493 #ifdef RESOLVE_VERBOSE
1494 printf("resolve_method_verifier_checks\n");
1495 printf(" flags: %02x\n",mi->flags);
1498 /* get the classinfos and the method descriptor */
1500 referer = refmethod->class;
1503 declarer = mi->class;
1505 assert(referer->state & CLASS_LINKED);
1507 md = methodref->parseddesc.md;
1511 instancecount = (invokestatic) ? 0 : 1;
1515 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1516 /* a static method is accessed via an instance, or vice versa */
1518 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1519 (mi->flags & ACC_STATIC) ? "static method called via instance"
1520 : "instance method called without instance");
1521 return resolveFailed;
1524 /* check access rights */
1526 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1530 /* XXX clean this up. this should be in exceptions.c */
1531 msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
1532 utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
1533 message = MNEW(char, msglen);
1534 strcpy(message, "method is not accessible (");
1535 utf_cat_classname(message, declarer->name);
1536 strcat(message, ".");
1537 utf_cat(message, mi->name);
1538 utf_cat(message, mi->descriptor);
1539 strcat(message," from ");
1540 utf_cat_classname(message, referer->name);
1541 strcat(message,")");
1542 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1543 MFREE(message, char, msglen);
1544 return resolveFailed; /* exception */
1549 return resolveSucceeded;
1551 #endif /* defined(ENABLE_VERIFIER) */
1554 /* resolve_method_type_checks **************************************************
1556 Check parameter types of a method invocation.
1559 jd...............jitdata of the method doing the call
1560 refmethod........the method containing the reference
1561 iptr.............the invoke instruction
1562 mi...............the methodinfo of the resolved method
1563 invokestatic.....true if the method is invoked by INVOKESTATIC
1564 invokespecial....true if the method is invoked by INVOKESPECIAL
1567 resolveSucceeded....everything ok
1568 resolveDeferred.....tests could not be done, have been deferred
1569 resolveFailed.......exception has been thrown
1571 *******************************************************************************/
1573 #if defined(ENABLE_VERIFIER)
1574 resolve_result_t resolve_method_type_checks(jitdata *jd,
1575 methodinfo *refmethod,
1581 varinfo *instanceslot;
1584 resolve_result_t result;
1586 typedesc *paramtypes;
1591 /* for non-static methods we have to check the constraints on the */
1598 instanceslot = NULL;
1602 instanceslot = VAR(iptr->sx.s23.s2.args[0]);
1605 assert((instanceslot && instancecount == 1) || invokestatic);
1607 /* record subtype constraints for the instance type, if any */
1611 assert(instanceslot->type == TYPE_ADR);
1613 if (invokespecial && TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1614 { /* XXX clean up */
1615 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1616 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1617 : CLASSREF_OR_CLASSINFO(refmethod->class);
1619 if (!typeinfo_init_class(tip,initclass))
1623 tip = &(instanceslot->typeinfo);
1626 result = resolve_lazy_subtype_checks(refmethod,
1628 CLASSREF_OR_CLASSINFO(mi->class),
1629 resolveLinkageError);
1630 if (result != resolveSucceeded)
1633 /* check protected access */
1635 /* XXX use other `declarer` than mi->class? */
1636 if (((mi->flags & ACC_PROTECTED) != 0)
1637 && !SAME_PACKAGE(mi->class, refmethod->class))
1639 result = resolve_lazy_subtype_checks(refmethod,
1641 CLASSREF_OR_CLASSINFO(refmethod->class),
1642 resolveIllegalAccessError);
1643 if (result != resolveSucceeded)
1649 /* check subtype constraints for TYPE_ADR parameters */
1651 md = mi->parseddesc;
1652 paramtypes = md->paramtypes;
1654 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1655 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1656 type = md->paramtypes[i+instancecount].type;
1659 assert(type == param->type);
1661 if (type == TYPE_ADR) {
1662 result = resolve_lazy_subtype_checks(refmethod,
1664 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1665 resolveLinkageError);
1666 if (result != resolveSucceeded)
1673 return resolveSucceeded;
1675 #endif /* defined(ENABLE_VERIFIER) */
1678 /* resolve_method_loading_constraints ******************************************
1680 Impose loading constraints on the parameters and return type of the
1684 referer..........the class refering to the method
1685 mi...............the method
1688 true................everything ok
1689 false...............an exception has been thrown
1691 *******************************************************************************/
1693 #if defined(ENABLE_VERIFIER)
1694 bool resolve_method_loading_constraints(classinfo *referer,
1698 typedesc *paramtypes;
1703 /* impose loading constraints on parameters (including instance) */
1705 md = mi->parseddesc;
1706 paramtypes = md->paramtypes;
1707 instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1709 for (i = 0; i < md->paramcount; i++) {
1710 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1711 if (i < instancecount) {
1712 /* The type of the 'this' pointer is the class containing */
1713 /* the method definition. Since container is the same as, */
1714 /* or a subclass of declarer, we also constrain declarer */
1715 /* by transitivity of loading constraints. */
1716 name = mi->class->name;
1719 name = paramtypes[i].classref->name;
1722 /* The caller (referer) and the callee (container) must agree */
1723 /* on the types of the parameters. */
1724 if (!classcache_add_constraint(referer->classloader,
1725 mi->class->classloader, name))
1726 return false; /* exception */
1730 /* impose loading constraint onto return type */
1732 if (md->returntype.type == TYPE_ADR) {
1733 /* The caller (referer) and the callee (container) must agree */
1734 /* on the return type. */
1735 if (!classcache_add_constraint(referer->classloader,
1736 mi->class->classloader,
1737 md->returntype.classref->name))
1738 return false; /* exception */
1745 #endif /* defined(ENABLE_VERIFIER) */
1748 /* resolve_method_lazy *********************************************************
1750 Resolve an unresolved method reference lazily
1752 NOTE: This function does NOT do any verification checks. In case of a
1753 successful resolution, you must call resolve_method_verifier_checks
1754 in order to perform the necessary checks!
1757 refmethod........the referer method
1758 methodref........the method reference
1759 invokespecial....true if this is an INVOKESPECIAL instruction
1762 resolveSucceeded.....the reference has been resolved
1763 resolveDeferred......the resolving could not be performed lazily
1764 resolveFailed........resolving failed, an exception has been thrown.
1766 *******************************************************************************/
1768 resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1769 constant_FMIref *methodref,
1773 classinfo *container;
1778 #ifdef RESOLVE_VERBOSE
1779 printf("resolve_method_lazy\n");
1782 /* the class containing the reference */
1784 referer = refmethod->class;
1787 /* check if the method itself is already resolved */
1789 if (IS_FMIREF_RESOLVED(methodref))
1790 return resolveSucceeded;
1792 /* first we must resolve the class containg the method */
1794 if (!resolve_class_from_name(referer, refmethod,
1795 methodref->p.classref->name, resolveLazy, true, true, &container))
1797 /* the class reference could not be resolved */
1798 return resolveFailed; /* exception */
1801 return resolveDeferred; /* be lazy */
1803 assert(container->state & CLASS_LINKED);
1805 /* now we must find the declaration of the method in `container`
1806 * or one of its superclasses */
1808 if (container->flags & ACC_INTERFACE) {
1809 mi = class_resolveinterfacemethod(container,
1811 methodref->descriptor,
1815 mi = class_resolveclassmethod(container,
1817 methodref->descriptor,
1822 /* The method does not exist. But since we were called lazily, */
1823 /* this error must not be reported now. (It will be reported */
1824 /* if eager resolving of this method is ever tried.) */
1826 *exceptionptr = NULL;
1827 return resolveDeferred; /* be lazy */
1830 if (invokespecial) {
1831 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1833 return resolveFailed; /* exception */
1836 /* have the method params already been parsed? no, do it. */
1838 if (!mi->parseddesc->params)
1839 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1840 return resolveFailed;
1842 /* cache the result of the resolution */
1844 methodref->p.method = mi;
1848 return resolveSucceeded;
1851 /* resolve_method **************************************************************
1853 Resolve an unresolved method reference
1856 ref..............struct containing the reference
1857 mode.............mode of resolution:
1858 resolveLazy...only resolve if it does not
1859 require loading classes
1860 resolveEager..load classes if necessary
1863 *result..........set to the result of resolution, or to NULL if
1864 the reference has not been resolved
1865 In the case of an exception, *result is
1866 guaranteed to be set to NULL.
1869 true.............everything ok
1870 (*result may still be NULL for resolveLazy)
1871 false............an exception has been thrown
1873 *******************************************************************************/
1875 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1878 classinfo *container;
1879 classinfo *declarer;
1881 typedesc *paramtypes;
1884 resolve_result_t checkresult;
1888 assert(mode == resolveLazy || mode == resolveEager);
1890 #ifdef RESOLVE_VERBOSE
1891 unresolved_method_debug_dump(ref,stdout);
1896 /* the class containing the reference */
1898 referer = ref->referermethod->class;
1901 /* check if the method itself is already resolved */
1903 if (IS_FMIREF_RESOLVED(ref->methodref)) {
1904 mi = ref->methodref->p.method;
1905 container = mi->class;
1906 goto resolved_the_method;
1909 /* first we must resolve the class containing the method */
1911 if (!resolve_class_from_name(referer,ref->referermethod,
1912 ref->methodref->p.classref->name,mode,true,true,&container))
1914 /* the class reference could not be resolved */
1915 return false; /* exception */
1918 return true; /* be lazy */
1921 assert(container->state & CLASS_LINKED);
1923 /* now we must find the declaration of the method in `container`
1924 * or one of its superclasses */
1926 if (container->flags & ACC_INTERFACE) {
1927 mi = class_resolveinterfacemethod(container,
1928 ref->methodref->name,
1929 ref->methodref->descriptor,
1933 mi = class_resolveclassmethod(container,
1934 ref->methodref->name,
1935 ref->methodref->descriptor,
1940 if (mode == resolveLazy) {
1941 /* The method does not exist. But since we were called lazily, */
1942 /* this error must not be reported now. (It will be reported */
1943 /* if eager resolving of this method is ever tried.) */
1945 *exceptionptr = NULL;
1946 return true; /* be lazy */
1949 return false; /* exception */ /* XXX set exceptionptr? */
1952 /* { the method reference has been resolved } */
1954 if (ref->flags & RESOLVE_SPECIAL) {
1955 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
1957 return false; /* exception */
1960 /* have the method params already been parsed? no, do it. */
1962 if (!mi->parseddesc->params)
1963 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1966 /* cache the resolution */
1968 ref->methodref->p.method = mi;
1970 resolved_the_method:
1972 #ifdef ENABLE_VERIFIER
1973 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1974 /* that no missing parts of an instruction will be accessed. */
1977 checkresult = resolve_method_verifier_checks(NULL,
1982 (ref->flags & RESOLVE_STATIC),
1983 (ref->flags & RESOLVE_SPECIAL),
1986 if (checkresult != resolveSucceeded)
1987 return (bool) checkresult;
1989 /* impose loading constraints on params and return type */
1991 if (!resolve_method_loading_constraints(referer, mi))
1994 declarer = mi->class;
1996 assert(referer->state & CLASS_LINKED);
1998 /* for non-static methods we have to check the constraints on the */
2001 if (!(ref->flags & RESOLVE_STATIC)) {
2002 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2003 &(ref->instancetypes),
2004 CLASSREF_OR_CLASSINFO(container),
2006 resolveLinkageError);
2007 if (checkresult != resolveSucceeded)
2008 return (bool) checkresult;
2015 /* check subtype constraints for TYPE_ADR parameters */
2017 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2018 paramtypes = mi->parseddesc->paramtypes;
2020 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2021 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2022 if (ref->paramconstraints) {
2023 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2024 ref->paramconstraints + i,
2025 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2027 resolveLinkageError);
2028 if (checkresult != resolveSucceeded)
2029 return (bool) checkresult;
2034 /* check protected access */
2036 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2038 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2039 &(ref->instancetypes),
2040 CLASSREF_OR_CLASSINFO(referer),
2042 resolveIllegalAccessError);
2043 if (checkresult != resolveSucceeded)
2044 return (bool) checkresult;
2047 #endif /* ENABLE_VERIFIER */
2054 /* resolve_method_eager ********************************************************
2056 Resolve an unresolved method reference eagerly.
2059 ref..............struct containing the reference
2062 methodinfo * to the method, or
2063 NULL if an exception has been thrown
2065 *******************************************************************************/
2067 methodinfo * resolve_method_eager(unresolved_method *ref)
2071 if (!resolve_method(ref,resolveEager,&mi))
2077 /******************************************************************************/
2078 /* CREATING THE DATA STRUCTURES */
2079 /******************************************************************************/
2081 #ifdef ENABLE_VERIFIER
2082 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2083 methodinfo *refmethod,
2084 unresolved_subtype_set *stset,
2086 utf *declaredclassname)
2094 #ifdef RESOLVE_VERBOSE
2095 printf("unresolved_subtype_set_from_typeinfo\n");
2096 #ifdef TYPEINFO_DEBUG
2097 typeinfo_print(stdout,tinfo,4);
2099 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2103 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2104 exceptions_throw_verifyerror(refmethod,
2105 "Invalid use of returnAddress");
2109 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2110 exceptions_throw_verifyerror(refmethod,
2111 "Invalid use of uninitialized object");
2115 /* the nulltype is always assignable */
2116 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2119 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2120 if (declaredclassname == utf_java_lang_Object
2121 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2126 if (tinfo->merged) {
2127 count = tinfo->merged->count;
2128 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2129 for (i=0; i<count; ++i) {
2130 classref_or_classinfo c = tinfo->merged->list[i];
2131 if (tinfo->dimension > 0) {
2132 /* a merge of array types */
2133 /* the merged list contains the possible _element_ types, */
2134 /* so we have to create array types with these elements. */
2135 if (IS_CLASSREF(c)) {
2136 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2139 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2142 stset->subtyperefs[i] = c;
2144 stset->subtyperefs[count].any = NULL; /* terminate */
2147 if ((IS_CLASSREF(tinfo->typeclass)
2148 ? tinfo->typeclass.ref->name
2149 : tinfo->typeclass.cls->name) == declaredclassname)
2151 /* the class names are the same */
2152 /* equality is guaranteed by the loading constraints */
2156 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2157 stset->subtyperefs[0] = tinfo->typeclass;
2158 stset->subtyperefs[1].any = NULL; /* terminate */
2165 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2168 #endif /* ENABLE_VERIFIER */
2170 /* create_unresolved_class *****************************************************
2172 Create an unresolved_class struct for the given class reference
2175 refmethod........the method triggering the resolution (if any)
2176 classref.........the class reference
2177 valuetype........value type to check against the resolved class
2178 may be NULL, if no typeinfo is available
2181 a pointer to a new unresolved_class struct, or
2182 NULL if an exception has been thrown
2184 *******************************************************************************/
2186 #ifdef ENABLE_VERIFIER
2187 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2188 constant_classref *classref,
2189 typeinfo *valuetype)
2191 unresolved_class *ref;
2193 #ifdef RESOLVE_VERBOSE
2194 printf("create_unresolved_class\n");
2195 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2197 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2198 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2200 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2203 ref = NEW(unresolved_class);
2204 ref->classref = classref;
2205 ref->referermethod = refmethod;
2208 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2209 &(ref->subtypeconstraints),valuetype,classref->name))
2213 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2218 #endif /* ENABLE_VERIFIER */
2220 /* resolve_create_unresolved_field *********************************************
2222 Create an unresolved_field struct for the given field access instruction
2225 referer..........the class containing the reference
2226 refmethod........the method triggering the resolution (if any)
2227 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2230 a pointer to a new unresolved_field struct, or
2231 NULL if an exception has been thrown
2233 *******************************************************************************/
2235 unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2236 methodinfo *refmethod,
2239 unresolved_field *ref;
2240 constant_FMIref *fieldref = NULL;
2242 #ifdef RESOLVE_VERBOSE
2243 printf("create_unresolved_field\n");
2244 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2245 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2246 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2249 ref = NEW(unresolved_field);
2251 ref->referermethod = refmethod;
2252 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2254 switch (iptr->opc) {
2256 ref->flags |= RESOLVE_PUTFIELD;
2259 case ICMD_PUTFIELDCONST:
2260 ref->flags |= RESOLVE_PUTFIELD;
2263 case ICMD_PUTSTATIC:
2264 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2267 case ICMD_PUTSTATICCONST:
2268 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2274 case ICMD_GETSTATIC:
2275 ref->flags |= RESOLVE_STATIC;
2278 #if !defined(NDEBUG)
2284 fieldref = iptr->sx.s23.s3.fmiref;
2288 #ifdef RESOLVE_VERBOSE
2289 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2290 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2291 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2292 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2294 /*printf(" opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2297 ref->fieldref = fieldref;
2302 /* resolve_constrain_unresolved_field ******************************************
2304 Record subtype constraints for a field access.
2307 ref..............the unresolved_field structure of the access
2308 referer..........the class containing the reference
2309 refmethod........the method triggering the resolution (if any)
2310 instanceti.......instance typeinfo, if available
2311 valueti..........value typeinfo, if available
2314 true.............everything ok
2315 false............an exception has been thrown
2317 *******************************************************************************/
2319 #if defined(ENABLE_VERIFIER)
2320 bool resolve_constrain_unresolved_field(unresolved_field *ref,
2322 methodinfo *refmethod,
2323 typeinfo *instanceti,
2326 constant_FMIref *fieldref;
2333 fieldref = ref->fieldref;
2336 #ifdef RESOLVE_VERBOSE
2337 printf("constrain_unresolved_field\n");
2338 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2339 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2340 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2341 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2342 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2343 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2344 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2346 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2349 assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2350 fd = fieldref->parseddesc.fd;
2353 /* record subtype constraints for the instance type, if any */
2357 /* The instanceslot must contain a reference to a non-array type */
2358 if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
2359 exceptions_throw_verifyerror(refmethod,
2360 "illegal instruction: field access on non-reference");
2363 if (TYPEINFO_IS_ARRAY(*instanceti)) {
2364 exceptions_throw_verifyerror(refmethod,
2365 "illegal instruction: field access on array");
2369 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2370 TYPEINFO_IS_NEWOBJECT(*instanceti))
2372 /* The instruction writes a field in an uninitialized object. */
2373 /* This is only allowed when a field of an uninitialized 'this' object is */
2374 /* written inside an initialization method */
2376 classinfo *initclass;
2377 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
2380 exceptions_throw_verifyerror(refmethod,
2381 "accessing field of uninitialized object");
2384 /* XXX check that class of field == refmethod->class */
2385 initclass = refmethod->class; /* XXX classrefs */
2386 assert(initclass->state & CLASS_LOADED);
2387 assert(initclass->state & CLASS_LINKED);
2389 typeinfo_init_classinfo(&tinfo, initclass);
2393 insttip = instanceti;
2395 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2396 &(ref->instancetypes), insttip,
2397 FIELDREF_CLASSNAME(fieldref)))
2401 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2404 /* record subtype constraints for the value type, if any */
2406 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2408 if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2409 &(ref->valueconstraints), valueti,
2410 fieldref->parseddesc.fd->classref->name))
2414 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2419 #endif /* ENABLE_VERIFIER */
2421 /* resolve_create_unresolved_method ********************************************
2423 Create an unresolved_method struct for the given method invocation
2426 referer..........the class containing the reference
2427 refmethod........the method triggering the resolution (if any)
2428 iptr.............the INVOKE* instruction
2431 a pointer to a new unresolved_method struct, or
2432 NULL if an exception has been thrown
2434 *******************************************************************************/
2436 unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2437 methodinfo *refmethod,
2438 constant_FMIref *methodref,
2442 unresolved_method *ref;
2446 #ifdef RESOLVE_VERBOSE
2447 printf("create_unresolved_method\n");
2448 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2449 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2450 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2451 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2452 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2455 /* allocate params if necessary */
2456 if (!methodref->parseddesc.md->params)
2457 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2458 (invokestatic) ? ACC_STATIC : ACC_NONE))
2461 /* create the data structure */
2462 ref = NEW(unresolved_method);
2463 ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2464 | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2465 ref->referermethod = refmethod;
2466 ref->methodref = methodref;
2467 ref->paramconstraints = NULL;
2468 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2473 /* constrain_unresolved_method *********************************************
2475 Record subtype constraints for the arguments of a method call.
2478 ref..............the unresolved_method structure of the call
2479 referer..........the class containing the reference
2480 refmethod........the method triggering the resolution (if any)
2481 iptr.............the INVOKE* instruction
2484 true.............everything ok
2485 false............an exception has been thrown
2487 *******************************************************************************/
2489 #ifdef ENABLE_VERIFIER
2490 bool constrain_unresolved_method(jitdata *jd,
2491 unresolved_method *ref,
2492 classinfo *referer, methodinfo *refmethod,
2495 constant_FMIref *methodref;
2496 constant_classref *instanceref;
2497 varinfo *instanceslot = NULL;
2506 methodref = ref->methodref;
2508 md = methodref->parseddesc.md;
2510 assert(md->params != NULL);
2512 /* XXX clean this up */
2513 instanceref = IS_FMIREF_RESOLVED(methodref)
2514 ? class_get_self_classref(methodref->p.method->class)
2515 : methodref->p.classref;
2517 #ifdef RESOLVE_VERBOSE
2518 printf("constrain_unresolved_method\n");
2519 printf(" referer: "); class_println(referer);
2520 printf(" rmethod: "); method_println(refmethod);
2521 printf(" mref : "); method_methodref_println(methodref);
2522 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2525 if ((ref->flags & RESOLVE_STATIC) == 0) {
2526 /* find the instance slot under all the parameter slots on the stack */
2527 instanceslot = VAR(iptr->sx.s23.s2.args[0]);
2534 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
2536 /* record subtype constraints for the instance type, if any */
2540 assert(instanceslot->type == TYPE_ADR);
2542 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
2543 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2544 { /* XXX clean up */
2545 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2546 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2547 : CLASSREF_OR_CLASSINFO(refmethod->class);
2549 if (!typeinfo_init_class(tip,initclass))
2553 tip = &(instanceslot->typeinfo);
2555 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2556 &(ref->instancetypes),tip,instanceref->name))
2560 /* record subtype constraints for the parameter types, if any */
2561 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2562 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2563 type = md->paramtypes[i+instancecount].type;
2566 assert(type == param->type);
2568 if (type == TYPE_ADR) {
2569 if (!ref->paramconstraints) {
2570 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2571 for (j=md->paramcount-1-instancecount; j>i; --j)
2572 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2574 assert(ref->paramconstraints);
2575 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2576 ref->paramconstraints + i,&(param->typeinfo),
2577 md->paramtypes[i+instancecount].classref->name))
2581 if (ref->paramconstraints)
2582 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2588 #endif /* ENABLE_VERIFIER */
2590 /******************************************************************************/
2591 /* FREEING MEMORY */
2592 /******************************************************************************/
2594 #ifdef ENABLE_VERIFIER
2595 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2598 classref_or_classinfo *p = list;
2600 /* this is silly. we *only* need to count the elements for MFREE */
2603 MFREE(list,classref_or_classinfo,(p - list));
2606 #endif /* ENABLE_VERIFIER */
2608 /* unresolved_class_free *******************************************************
2610 Free the memory used by an unresolved_class
2613 ref..............the unresolved_class
2615 *******************************************************************************/
2617 void unresolved_class_free(unresolved_class *ref)
2621 #ifdef ENABLE_VERIFIER
2622 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2624 FREE(ref,unresolved_class);
2627 /* unresolved_field_free *******************************************************
2629 Free the memory used by an unresolved_field
2632 ref..............the unresolved_field
2634 *******************************************************************************/
2636 void unresolved_field_free(unresolved_field *ref)
2640 #ifdef ENABLE_VERIFIER
2641 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2642 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2644 FREE(ref,unresolved_field);
2647 /* unresolved_method_free ******************************************************
2649 Free the memory used by an unresolved_method
2652 ref..............the unresolved_method
2654 *******************************************************************************/
2656 void unresolved_method_free(unresolved_method *ref)
2660 #ifdef ENABLE_VERIFIER
2661 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2662 if (ref->paramconstraints) {
2664 int count = ref->methodref->parseddesc.md->paramcount;
2666 for (i=0; i<count; ++i)
2667 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2668 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2671 FREE(ref,unresolved_method);
2674 /******************************************************************************/
2676 /******************************************************************************/
2678 #if !defined(NDEBUG)
2680 /* unresolved_subtype_set_debug_dump *******************************************
2682 Print debug info for unresolved_subtype_set to stream
2685 stset............the unresolved_subtype_set
2686 file.............the stream
2688 *******************************************************************************/
2690 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2692 classref_or_classinfo *p;
2694 if (SUBTYPESET_IS_EMPTY(*stset)) {
2695 fprintf(file," (empty)\n");
2698 p = stset->subtyperefs;
2699 for (;p->any; ++p) {
2700 if (IS_CLASSREF(*p)) {
2701 fprintf(file," ref: ");
2702 utf_fprint_printable_ascii(file,p->ref->name);
2705 fprintf(file," cls: ");
2706 utf_fprint_printable_ascii(file,p->cls->name);
2713 /* unresolved_class_debug_dump *************************************************
2715 Print debug info for unresolved_class to stream
2718 ref..............the unresolved_class
2719 file.............the stream
2721 *******************************************************************************/
2723 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2725 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2727 fprintf(file," referer : ");
2728 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2729 fprintf(file," refmethod : ");
2730 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2731 fprintf(file," refmethodd: ");
2732 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2733 fprintf(file," classname : ");
2734 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2735 fprintf(file," subtypeconstraints:\n");
2736 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2740 /* unresolved_field_debug_dump *************************************************
2742 Print debug info for unresolved_field to stream
2745 ref..............the unresolved_field
2746 file.............the stream
2748 *******************************************************************************/
2750 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2752 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
2754 fprintf(file," referer : ");
2755 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2756 fprintf(file," refmethod : ");
2757 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2758 fprintf(file," refmethodd: ");
2759 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2760 fprintf(file," classname : ");
2761 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
2762 fprintf(file," name : ");
2763 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
2764 fprintf(file," descriptor: ");
2765 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
2766 fprintf(file," parseddesc: ");
2767 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
2768 fprintf(file," flags : %04x\n",ref->flags);
2769 fprintf(file," instancetypes:\n");
2770 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2771 fprintf(file," valueconstraints:\n");
2772 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2776 /* unresolved_method_debug_dump ************************************************
2778 Print debug info for unresolved_method to stream
2781 ref..............the unresolved_method
2782 file.............the stream
2784 *******************************************************************************/
2786 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2790 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2792 fprintf(file," referer : ");
2793 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2794 fprintf(file," refmethod : ");
2795 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2796 fprintf(file," refmethodd: ");
2797 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2798 fprintf(file," classname : ");
2799 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
2800 fprintf(file," name : ");
2801 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
2802 fprintf(file," descriptor: ");
2803 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
2804 fprintf(file," parseddesc: ");
2805 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2806 fprintf(file," flags : %04x\n",ref->flags);
2807 fprintf(file," instancetypes:\n");
2808 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2809 fprintf(file," paramconstraints:\n");
2810 if (ref->paramconstraints) {
2811 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2812 fprintf(file," param %d:\n",i);
2813 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2817 fprintf(file," (empty)\n");
2821 #endif /* !defined(NDEBUG) */
2824 * These are local overrides for various environment variables in Emacs.
2825 * Please do not remove this and leave it at the end of the file, where
2826 * Emacs will automagically detect them.
2827 * ---------------------------------------------------------------------
2830 * indent-tabs-mode: t
2834 * vim:noexpandtab:sw=4:ts=4: