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 5655 2006-10-03 20:44:46Z 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 opc..............opcode of the {GET,PUT}{STATIC,FIELD} instruction
943 iptr.............field instruction or NULL
946 resolveSucceeded....everything ok
947 resolveDeferred.....tests could not be done, have been deferred
948 resolveFailed.......exception has been thrown
950 *******************************************************************************/
952 #if defined(ENABLE_VERIFIER)
953 resolve_result_t resolve_field_verifier_checks(jitdata *jd,
954 methodinfo *refmethod,
955 constant_FMIref *fieldref,
956 classinfo *container,
963 resolve_result_t result;
964 bool isstatic = false;
966 varinfo *instanceslot = NULL;
967 varinfo *valueslot = NULL;
968 constant_classref *fieldtyperef;
976 /* get the classinfos and the field type */
978 referer = refmethod->class;
981 declarer = fi->class;
983 assert(referer->state & CLASS_LINKED);
985 fieldtyperef = fieldref->parseddesc.fd->classref;
987 /* get opcode dependent values */
993 valueslot = VAROP(iptr->sx.s23.s2);
994 instanceslot = VAROP(iptr->s1);
998 case ICMD_PUTFIELDCONST:
1001 instanceslot = VAROP(iptr->s1);
1004 case ICMD_PUTSTATIC:
1008 valueslot = VAROP(iptr->s1);
1011 case ICMD_PUTSTATICCONST:
1018 instanceslot = VAROP(iptr->s1);
1021 case ICMD_GETSTATIC:
1029 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1032 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1033 /* a static field is accessed via an instance, or vice versa */
1035 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1036 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
1037 : "instance field accessed without instance");
1038 return resolveFailed;
1041 /* check access rights */
1043 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1047 msglen = utf_bytes(declarer->name) + utf_bytes(fi->name) + utf_bytes(referer->name) + 100;
1048 message = MNEW(char, msglen);
1049 strcpy(message, "field is not accessible (");
1050 utf_cat_classname(message, declarer->name);
1051 strcat(message, ".");
1052 utf_cat(message, fi->name);
1053 strcat(message, " from ");
1054 utf_cat_classname(message, referer->name);
1055 strcat(message, ")");
1056 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1057 MFREE(message,char,msglen);
1058 return resolveFailed; /* exception */
1061 /* for non-static methods we have to check the constraints on the */
1068 /* The instanceslot must contain a reference to a non-array type */
1070 assert(instanceslot->type == TYPE_ADR); /* checked earlier */
1072 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
1073 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1074 return resolveFailed;
1076 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
1077 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1078 return resolveFailed;
1081 if (isput && TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1083 /* The instruction writes a field in an uninitialized object. */
1084 /* This is only allowed when a field of an uninitialized 'this' object is */
1085 /* written inside an initialization method */
1087 classinfo *initclass;
1088 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1091 exceptions_throw_verifyerror(refmethod,"accessing field of uninitialized object");
1092 return resolveFailed;
1095 /* XXX check that class of field == refmethod->class */
1096 initclass = referer; /* XXX classrefs */
1097 assert(initclass->state & CLASS_LINKED);
1099 typeinfo_init_classinfo(&tinfo,initclass);
1103 insttip = &(instanceslot->typeinfo);
1106 result = resolve_lazy_subtype_checks(refmethod,
1108 CLASSREF_OR_CLASSINFO(container),
1109 resolveLinkageError);
1110 if (result != resolveSucceeded)
1113 /* check protected access */
1115 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1117 result = resolve_lazy_subtype_checks(refmethod,
1118 &(instanceslot->typeinfo),
1119 CLASSREF_OR_CLASSINFO(referer),
1120 resolveIllegalAccessError);
1121 if (result != resolveSucceeded)
1127 /* for PUT* instructions we have to check the constraints on the value type */
1129 if (valueslot && valueslot->type == TYPE_ADR) {
1130 assert(fieldtyperef);
1132 /* check subtype constraints */
1133 result = resolve_lazy_subtype_checks(refmethod,
1134 &(valueslot->typeinfo),
1135 CLASSREF_OR_CLASSINFO(fieldtyperef),
1136 resolveLinkageError);
1138 if (result != resolveSucceeded)
1142 /* impose loading constraint on field type */
1144 if (fi->type == TYPE_ADR) {
1145 assert(fieldtyperef);
1146 if (!classcache_add_constraint(declarer->classloader,
1147 referer->classloader,
1148 fieldtyperef->name))
1149 return resolveFailed;
1152 /* XXX impose loading constraing on instance? */
1155 return resolveSucceeded;
1157 #endif /* defined(ENABLE_VERIFIER) */
1159 /* resolve_field_lazy **********************************************************
1161 Resolve an unresolved field reference lazily
1164 iptr.............instruction containing the field reference
1165 refmethod........the referer method
1168 resolveSucceeded.....the reference has been resolved
1169 resolveDeferred......the resolving could not be performed lazily
1170 resolveFailed........resolving failed, an exception has been thrown.
1172 *******************************************************************************/
1174 resolve_result_t resolve_field_lazy(jitdata *jd,
1176 methodinfo *refmethod)
1179 classinfo *container;
1181 constant_FMIref *fieldref;
1182 resolve_result_t result;
1187 /* the class containing the reference */
1189 referer = refmethod->class;
1192 /* get the field reference */
1194 INSTRUCTION_GET_FIELDREF(iptr, fieldref);
1196 /* check if the field itself is already resolved */
1198 if (IS_FMIREF_RESOLVED(fieldref)) {
1199 fi = fieldref->p.field;
1200 container = fi->class;
1201 goto resolved_the_field;
1204 /* first we must resolve the class containg the field */
1206 /* XXX can/may lazyResolving trigger linking? */
1208 if (!resolve_class_from_name(referer, refmethod,
1209 fieldref->p.classref->name, resolveLazy, true, true, &container))
1211 /* the class reference could not be resolved */
1212 return resolveFailed; /* exception */
1215 return resolveDeferred; /* be lazy */
1217 assert(container->state & CLASS_LINKED);
1219 /* now we must find the declaration of the field in `container`
1220 * or one of its superclasses */
1222 fi = class_resolvefield(container,
1223 fieldref->name, fieldref->descriptor,
1226 /* The field does not exist. But since we were called lazily, */
1227 /* this error must not be reported now. (It will be reported */
1228 /* if eager resolving of this field is ever tried.) */
1230 *exceptionptr = NULL;
1231 return resolveDeferred; /* be lazy */
1234 /* cache the result of the resolution */
1236 fieldref->p.field = fi;
1240 #if defined(ENABLE_VERIFIER)
1241 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
1242 result = resolve_field_verifier_checks(jd,
1243 refmethod, fieldref, container, fi,
1246 if (result != resolveSucceeded)
1249 #endif /* defined(ENABLE_VERIFIER) */
1252 return resolveSucceeded;
1255 /* resolve_field ***************************************************************
1257 Resolve an unresolved field reference
1260 ref..............struct containing the reference
1261 mode.............mode of resolution:
1262 resolveLazy...only resolve if it does not
1263 require loading classes
1264 resolveEager..load classes if necessary
1267 *result..........set to the result of resolution, or to NULL if
1268 the reference has not been resolved
1269 In the case of an exception, *result is
1270 guaranteed to be set to NULL.
1273 true.............everything ok
1274 (*result may still be NULL for resolveLazy)
1275 false............an exception has been thrown
1277 *******************************************************************************/
1279 bool resolve_field(unresolved_field *ref,
1280 resolve_mode_t mode,
1284 classinfo *container;
1285 classinfo *declarer;
1286 constant_classref *fieldtyperef;
1288 resolve_result_t checkresult;
1292 assert(mode == resolveLazy || mode == resolveEager);
1296 #ifdef RESOLVE_VERBOSE
1297 unresolved_field_debug_dump(ref,stdout);
1300 /* the class containing the reference */
1302 referer = ref->referermethod->class;
1305 /* check if the field itself is already resolved */
1306 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1307 fi = ref->fieldref->p.field;
1308 container = fi->class;
1309 goto resolved_the_field;
1312 /* first we must resolve the class containg the field */
1313 if (!resolve_class_from_name(referer,ref->referermethod,
1314 ref->fieldref->p.classref->name,mode,true,true,&container))
1316 /* the class reference could not be resolved */
1317 return false; /* exception */
1320 return true; /* be lazy */
1323 assert(container->state & CLASS_LOADED);
1324 assert(container->state & CLASS_LINKED);
1326 /* now we must find the declaration of the field in `container`
1327 * or one of its superclasses */
1329 #ifdef RESOLVE_VERBOSE
1330 printf(" resolving field in class...\n");
1333 fi = class_resolvefield(container,
1334 ref->fieldref->name,ref->fieldref->descriptor,
1337 if (mode == resolveLazy) {
1338 /* The field does not exist. But since we were called lazily, */
1339 /* this error must not be reported now. (It will be reported */
1340 /* if eager resolving of this field is ever tried.) */
1342 *exceptionptr = NULL;
1343 return true; /* be lazy */
1346 return false; /* exception */
1349 /* cache the result of the resolution */
1350 ref->fieldref->p.field = fi;
1354 #ifdef ENABLE_VERIFIER
1355 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1356 /* that no missing parts of an instruction will be accessed. */
1358 checkresult = resolve_field_verifier_checks(NULL,
1363 (ref->flags & RESOLVE_STATIC) ? ICMD_GETSTATIC : ICMD_GETFIELD,
1366 if (checkresult != resolveSucceeded)
1367 return (bool) checkresult;
1369 declarer = fi->class;
1371 assert(declarer->state & CLASS_LOADED);
1372 assert(declarer->state & CLASS_LINKED);
1374 /* for non-static accesses we have to check the constraints on the */
1377 if (!(ref->flags & RESOLVE_STATIC)) {
1378 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1379 &(ref->instancetypes),
1380 CLASSREF_OR_CLASSINFO(container),
1381 mode, resolveLinkageError);
1382 if (checkresult != resolveSucceeded)
1383 return (bool) checkresult;
1386 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1388 /* for PUT* instructions we have to check the constraints on the value type */
1389 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1390 assert(fieldtyperef);
1391 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1392 /* check subtype constraints */
1393 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1394 &(ref->valueconstraints),
1395 CLASSREF_OR_CLASSINFO(fieldtyperef),
1396 mode, resolveLinkageError);
1397 if (checkresult != resolveSucceeded)
1398 return (bool) checkresult;
1402 /* check protected access */
1403 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1404 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1405 &(ref->instancetypes),
1406 CLASSREF_OR_CLASSINFO(referer),
1408 resolveIllegalAccessError);
1409 if (checkresult != resolveSucceeded)
1410 return (bool) checkresult;
1414 #endif /* ENABLE_VERIFIER */
1422 /* resolve_field_eager *********************************************************
1424 Resolve an unresolved field reference eagerly.
1427 ref..............struct containing the reference
1430 fieldinfo * to the field, or
1431 NULL if an exception has been thrown
1433 *******************************************************************************/
1435 fieldinfo * resolve_field_eager(unresolved_field *ref)
1439 if (!resolve_field(ref,resolveEager,&fi))
1445 /******************************************************************************/
1446 /* METHOD RESOLUTION */
1447 /******************************************************************************/
1449 /* resolve_method_invokespecial_lookup *****************************************
1451 Do the special lookup for methods invoked by INVOKESPECIAL
1454 refmethod........the method containing the reference
1455 mi...............the methodinfo of the resolved method
1458 a methodinfo *...the result of the lookup,
1459 NULL.............an exception has been thrown
1461 *******************************************************************************/
1463 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1466 classinfo *declarer;
1472 /* get referer and declarer classes */
1474 referer = refmethod->class;
1477 declarer = mi->class;
1479 assert(referer->state & CLASS_LINKED);
1481 /* checks for INVOKESPECIAL: */
1482 /* for <init> and methods of the current class we don't need any */
1483 /* special checks. Otherwise we must verify that the called method */
1484 /* belongs to a super class of the current class */
1486 if ((referer != declarer) && (mi->name != utf_init)) {
1487 /* check that declarer is a super class of the current class */
1489 if (!class_issubclass(referer,declarer)) {
1490 exceptions_throw_verifyerror(refmethod,
1491 "INVOKESPECIAL calling non-super class method");
1495 /* if the referer has ACC_SUPER set, we must do the special */
1496 /* lookup starting with the direct super class of referer */
1498 if ((referer->flags & ACC_SUPER) != 0) {
1499 mi = class_resolvemethod(referer->super.cls,
1504 /* the spec calls for an AbstractMethodError in this case */
1505 exceptions_throw_abstractmethoderror();
1515 /* resolve_method_verifier_checks ******************************************
1517 Do the verifier checks necessary after a method has been resolved.
1520 refmethod........the method containing the reference
1521 methodref........the method reference
1522 container........the class where the method was found
1523 mi...............the methodinfo of the resolved method
1524 invokestatic.....true if the method is invoked by INVOKESTATIC
1525 iptr.............the invoke instruction, or NULL
1528 resolveSucceeded....everything ok
1529 resolveDeferred.....tests could not be done, have been deferred
1530 resolveFailed.......exception has been thrown
1532 *******************************************************************************/
1534 #if defined(ENABLE_VERIFIER)
1535 resolve_result_t resolve_method_verifier_checks(jitdata *jd,
1536 methodinfo *refmethod,
1537 constant_FMIref *methodref,
1538 classinfo *container,
1544 classinfo *declarer;
1546 resolve_result_t result;
1548 typedesc *paramtypes;
1550 varinfo *instanceslot = NULL;
1561 #ifdef RESOLVE_VERBOSE
1562 printf("resolve_method_verifier_checks\n");
1563 printf(" flags: %02x\n",mi->flags);
1566 /* get the classinfos and the method descriptor */
1568 referer = refmethod->class;
1571 declarer = mi->class;
1573 assert(referer->state & CLASS_LINKED);
1575 md = methodref->parseddesc.md;
1579 instancecount = (invokestatic) ? 0 : 1;
1583 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1584 /* a static method is accessed via an instance, or vice versa */
1586 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1587 (mi->flags & ACC_STATIC) ? "static method called via instance"
1588 : "instance method called without instance");
1589 return resolveFailed;
1592 /* check access rights */
1594 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1598 /* XXX clean this up. this should be in exceptions.c */
1599 msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
1600 utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
1601 message = MNEW(char, msglen);
1602 strcpy(message, "method is not accessible (");
1603 utf_cat_classname(message, declarer->name);
1604 strcat(message, ".");
1605 utf_cat(message, mi->name);
1606 utf_cat(message, mi->descriptor);
1607 strcat(message," from ");
1608 utf_cat_classname(message, referer->name);
1609 strcat(message,")");
1610 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1611 MFREE(message, char, msglen);
1612 return resolveFailed; /* exception */
1616 /* for non-static methods we have to check the constraints on the */
1621 if (!invokestatic) {
1622 instanceslot = VAR(iptr->sx.s23.s2.args[0]);
1625 assert((instanceslot && instancecount == 1) || invokestatic);
1627 /* record subtype constraints for the instance type, if any */
1631 assert(instanceslot->type == TYPE_ADR);
1633 if (invokespecial &&
1634 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1635 { /* XXX clean up */
1636 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1637 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
1638 : CLASSREF_OR_CLASSINFO(refmethod->class);
1640 if (!typeinfo_init_class(tip,initclass))
1644 tip = &(instanceslot->typeinfo);
1647 result = resolve_lazy_subtype_checks(refmethod,
1649 CLASSREF_OR_CLASSINFO(container),
1650 resolveLinkageError);
1651 if (result != resolveSucceeded)
1654 /* check protected access */
1656 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1658 result = resolve_lazy_subtype_checks(refmethod,
1660 CLASSREF_OR_CLASSINFO(referer),
1661 resolveIllegalAccessError);
1662 if (result != resolveSucceeded)
1668 /* check subtype constraints for TYPE_ADR parameters */
1670 assert(md->paramcount == methodref->parseddesc.md->paramcount);
1671 paramtypes = md->paramtypes;
1673 for (i = md->paramcount-1-instancecount; i>=0; --i) {
1674 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1675 type = md->paramtypes[i+instancecount].type;
1678 assert(type == param->type);
1680 if (type == TYPE_ADR) {
1681 result = resolve_lazy_subtype_checks(refmethod,
1683 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1684 resolveLinkageError);
1685 if (result != resolveSucceeded)
1692 /* impose loading constraints on parameters (including instance) */
1694 paramtypes = md->paramtypes;
1696 for (i = 0; i < md->paramcount; i++) {
1697 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1700 if (i < instancecount) {
1701 /* The type of the 'this' pointer is the class containing */
1702 /* the method definition. Since container is the same as, */
1703 /* or a subclass of declarer, we also constrain declarer */
1704 /* by transitivity of loading constraints. */
1705 name = container->name;
1708 name = paramtypes[i].classref->name;
1711 /* The caller (referer) and the callee (container) must agree */
1712 /* on the types of the parameters. */
1713 if (!classcache_add_constraint(referer->classloader,
1714 container->classloader, name))
1715 return resolveFailed; /* exception */
1719 /* impose loading constraint onto return type */
1721 if (md->returntype.type == TYPE_ADR) {
1722 /* The caller (referer) and the callee (container) must agree */
1723 /* on the return type. */
1724 if (!classcache_add_constraint(referer->classloader,container->classloader,
1725 md->returntype.classref->name))
1726 return resolveFailed; /* exception */
1730 return resolveSucceeded;
1732 #endif /* defined(ENABLE_VERIFIER) */
1734 /* resolve_method_lazy *********************************************************
1736 Resolve an unresolved method reference lazily
1739 iptr.............instruction containing the method reference
1740 refmethod........the referer method
1743 resolveSucceeded.....the reference has been resolved
1744 resolveDeferred......the resolving could not be performed lazily
1745 resolveFailed........resolving failed, an exception has been thrown.
1747 *******************************************************************************/
1749 resolve_result_t resolve_method_lazy(jitdata *jd,
1751 methodinfo *refmethod)
1754 classinfo *container;
1756 constant_FMIref *methodref;
1757 resolve_result_t result;
1762 #ifdef RESOLVE_VERBOSE
1763 printf("resolve_method_lazy\n");
1766 /* the class containing the reference */
1768 referer = refmethod->class;
1771 /* the method reference */
1773 INSTRUCTION_GET_METHODREF(iptr, methodref);
1775 /* check if the method itself is already resolved */
1777 if (IS_FMIREF_RESOLVED(methodref)) {
1778 mi = methodref->p.method;
1779 container = mi->class;
1780 goto resolved_the_method;
1783 /* first we must resolve the class containg the method */
1785 if (!resolve_class_from_name(referer, refmethod,
1786 methodref->p.classref->name, resolveLazy, true, true, &container))
1788 /* the class reference could not be resolved */
1789 return resolveFailed; /* exception */
1792 return resolveDeferred; /* be lazy */
1794 assert(container->state & CLASS_LINKED);
1796 /* now we must find the declaration of the method in `container`
1797 * or one of its superclasses */
1799 if (container->flags & ACC_INTERFACE) {
1800 mi = class_resolveinterfacemethod(container,
1802 methodref->descriptor,
1806 mi = class_resolveclassmethod(container,
1808 methodref->descriptor,
1813 /* The method does not exist. But since we were called lazily, */
1814 /* this error must not be reported now. (It will be reported */
1815 /* if eager resolving of this method is ever tried.) */
1817 *exceptionptr = NULL;
1818 return resolveDeferred; /* be lazy */
1821 if (iptr->opc == ICMD_INVOKESPECIAL) {
1822 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1824 return resolveFailed; /* exception */
1827 /* have the method params already been parsed? no, do it. */
1829 if (!mi->parseddesc->params)
1830 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1831 return resolveFailed;
1833 /* cache the result of the resolution */
1835 methodref->p.method = mi;
1837 resolved_the_method:
1839 #if defined(ENABLE_VERIFIER)
1840 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
1841 result = resolve_method_verifier_checks(jd,
1842 refmethod, methodref,
1845 iptr->opc == ICMD_INVOKESTATIC,
1846 iptr->opc == ICMD_INVOKESPECIAL,
1848 if (result != resolveSucceeded)
1851 #endif /* defined(ENABLE_VERIFIER) */
1853 /* if this call is monomorphic, turn it into an INVOKESPECIAL */
1855 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1856 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1858 iptr->opc = ICMD_INVOKESPECIAL;
1862 return resolveSucceeded;
1865 /* resolve_method **************************************************************
1867 Resolve an unresolved method reference
1870 ref..............struct containing the reference
1871 mode.............mode of resolution:
1872 resolveLazy...only resolve if it does not
1873 require loading classes
1874 resolveEager..load classes if necessary
1877 *result..........set to the result of resolution, or to NULL if
1878 the reference has not been resolved
1879 In the case of an exception, *result is
1880 guaranteed to be set to NULL.
1883 true.............everything ok
1884 (*result may still be NULL for resolveLazy)
1885 false............an exception has been thrown
1887 *******************************************************************************/
1889 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
1892 classinfo *container;
1893 classinfo *declarer;
1895 typedesc *paramtypes;
1898 resolve_result_t checkresult;
1902 assert(mode == resolveLazy || mode == resolveEager);
1904 #ifdef RESOLVE_VERBOSE
1905 unresolved_method_debug_dump(ref,stdout);
1910 /* the class containing the reference */
1912 referer = ref->referermethod->class;
1915 /* check if the method itself is already resolved */
1917 if (IS_FMIREF_RESOLVED(ref->methodref)) {
1918 mi = ref->methodref->p.method;
1919 container = mi->class;
1920 goto resolved_the_method;
1923 /* first we must resolve the class containing the method */
1925 if (!resolve_class_from_name(referer,ref->referermethod,
1926 ref->methodref->p.classref->name,mode,true,true,&container))
1928 /* the class reference could not be resolved */
1929 return false; /* exception */
1932 return true; /* be lazy */
1935 assert(container->state & CLASS_LINKED);
1937 /* now we must find the declaration of the method in `container`
1938 * or one of its superclasses */
1940 if (container->flags & ACC_INTERFACE) {
1941 mi = class_resolveinterfacemethod(container,
1942 ref->methodref->name,
1943 ref->methodref->descriptor,
1947 mi = class_resolveclassmethod(container,
1948 ref->methodref->name,
1949 ref->methodref->descriptor,
1954 if (mode == resolveLazy) {
1955 /* The method does not exist. But since we were called lazily, */
1956 /* this error must not be reported now. (It will be reported */
1957 /* if eager resolving of this method is ever tried.) */
1959 *exceptionptr = NULL;
1960 return true; /* be lazy */
1963 return false; /* exception */ /* XXX set exceptionptr? */
1966 /* { the method reference has been resolved } */
1968 if (ref->flags & RESOLVE_SPECIAL) {
1969 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
1971 return false; /* exception */
1974 /* have the method params already been parsed? no, do it. */
1976 if (!mi->parseddesc->params)
1977 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1980 /* cache the resolution */
1982 ref->methodref->p.method = mi;
1984 resolved_the_method:
1986 #ifdef ENABLE_VERIFIER
1987 /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1988 /* that no missing parts of an instruction will be accessed. */
1991 checkresult = resolve_method_verifier_checks(NULL,
1996 (ref->flags & RESOLVE_STATIC),
1997 (ref->flags & RESOLVE_SPECIAL),
2000 if (checkresult != resolveSucceeded)
2001 return (bool) checkresult;
2003 declarer = mi->class;
2005 assert(referer->state & CLASS_LINKED);
2007 /* for non-static methods we have to check the constraints on the */
2010 if (!(ref->flags & RESOLVE_STATIC)) {
2011 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2012 &(ref->instancetypes),
2013 CLASSREF_OR_CLASSINFO(container),
2015 resolveLinkageError);
2016 if (checkresult != resolveSucceeded)
2017 return (bool) checkresult;
2024 /* check subtype constraints for TYPE_ADR parameters */
2026 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2027 paramtypes = mi->parseddesc->paramtypes;
2029 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2030 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2031 if (ref->paramconstraints) {
2032 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2033 ref->paramconstraints + i,
2034 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2036 resolveLinkageError);
2037 if (checkresult != resolveSucceeded)
2038 return (bool) checkresult;
2043 /* check protected access */
2045 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2047 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2048 &(ref->instancetypes),
2049 CLASSREF_OR_CLASSINFO(referer),
2051 resolveIllegalAccessError);
2052 if (checkresult != resolveSucceeded)
2053 return (bool) checkresult;
2056 #endif /* ENABLE_VERIFIER */
2063 /* resolve_method_eager ********************************************************
2065 Resolve an unresolved method reference eagerly.
2068 ref..............struct containing the reference
2071 methodinfo * to the method, or
2072 NULL if an exception has been thrown
2074 *******************************************************************************/
2076 methodinfo * resolve_method_eager(unresolved_method *ref)
2080 if (!resolve_method(ref,resolveEager,&mi))
2086 /******************************************************************************/
2087 /* CREATING THE DATA STRUCTURES */
2088 /******************************************************************************/
2090 #ifdef ENABLE_VERIFIER
2091 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2092 methodinfo *refmethod,
2093 unresolved_subtype_set *stset,
2095 utf *declaredclassname)
2103 #ifdef RESOLVE_VERBOSE
2104 printf("unresolved_subtype_set_from_typeinfo\n");
2105 #ifdef TYPEINFO_DEBUG
2106 typeinfo_print(stdout,tinfo,4);
2108 printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2112 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2113 exceptions_throw_verifyerror(refmethod,
2114 "Invalid use of returnAddress");
2118 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2119 exceptions_throw_verifyerror(refmethod,
2120 "Invalid use of uninitialized object");
2124 /* the nulltype is always assignable */
2125 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2128 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2129 if (declaredclassname == utf_java_lang_Object
2130 && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2135 if (tinfo->merged) {
2136 count = tinfo->merged->count;
2137 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2138 for (i=0; i<count; ++i) {
2139 classref_or_classinfo c = tinfo->merged->list[i];
2140 if (tinfo->dimension > 0) {
2141 /* a merge of array types */
2142 /* the merged list contains the possible _element_ types, */
2143 /* so we have to create array types with these elements. */
2144 if (IS_CLASSREF(c)) {
2145 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2148 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2151 stset->subtyperefs[i] = c;
2153 stset->subtyperefs[count].any = NULL; /* terminate */
2156 if ((IS_CLASSREF(tinfo->typeclass)
2157 ? tinfo->typeclass.ref->name
2158 : tinfo->typeclass.cls->name) == declaredclassname)
2160 /* the class names are the same */
2161 /* equality is guaranteed by the loading constraints */
2165 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2166 stset->subtyperefs[0] = tinfo->typeclass;
2167 stset->subtyperefs[1].any = NULL; /* terminate */
2174 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2177 #endif /* ENABLE_VERIFIER */
2179 /* create_unresolved_class *****************************************************
2181 Create an unresolved_class struct for the given class reference
2184 refmethod........the method triggering the resolution (if any)
2185 classref.........the class reference
2186 valuetype........value type to check against the resolved class
2187 may be NULL, if no typeinfo is available
2190 a pointer to a new unresolved_class struct, or
2191 NULL if an exception has been thrown
2193 *******************************************************************************/
2195 #ifdef ENABLE_VERIFIER
2196 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2197 constant_classref *classref,
2198 typeinfo *valuetype)
2200 unresolved_class *ref;
2202 #ifdef RESOLVE_VERBOSE
2203 printf("create_unresolved_class\n");
2204 printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2206 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2207 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2209 printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2212 ref = NEW(unresolved_class);
2213 ref->classref = classref;
2214 ref->referermethod = refmethod;
2217 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2218 &(ref->subtypeconstraints),valuetype,classref->name))
2222 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2227 #endif /* ENABLE_VERIFIER */
2229 /* create_unresolved_field *****************************************************
2231 Create an unresolved_field struct for the given field access instruction
2234 referer..........the class containing the reference
2235 refmethod........the method triggering the resolution (if any)
2236 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2239 a pointer to a new unresolved_field struct, or
2240 NULL if an exception has been thrown
2242 *******************************************************************************/
2244 unresolved_field * create_unresolved_field(classinfo *referer,
2245 methodinfo *refmethod,
2248 unresolved_field *ref;
2249 constant_FMIref *fieldref = NULL;
2251 #ifdef RESOLVE_VERBOSE
2252 printf("create_unresolved_field\n");
2253 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2254 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2255 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2258 ref = NEW(unresolved_field);
2260 ref->referermethod = refmethod;
2261 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2263 switch (iptr->opc) {
2265 ref->flags |= RESOLVE_PUTFIELD;
2268 case ICMD_PUTFIELDCONST:
2269 ref->flags |= RESOLVE_PUTFIELD;
2272 case ICMD_PUTSTATIC:
2273 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2276 case ICMD_PUTSTATICCONST:
2277 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2283 case ICMD_GETSTATIC:
2284 ref->flags |= RESOLVE_STATIC;
2287 #if !defined(NDEBUG)
2293 fieldref = iptr->sx.s23.s3.fmiref;
2297 #ifdef RESOLVE_VERBOSE
2298 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2299 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2300 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2301 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2303 /*printf(" opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2306 ref->fieldref = fieldref;
2311 /* constrain_unresolved_field **********************************************
2313 Record subtype constraints for a field access.
2316 ref..............the unresolved_field structure of the access
2317 referer..........the class containing the reference
2318 refmethod........the method triggering the resolution (if any)
2319 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2322 true.............everything ok
2323 false............an exception has been thrown
2325 *******************************************************************************/
2327 #ifdef ENABLE_VERIFIER
2328 bool constrain_unresolved_field(jitdata *jd,
2329 unresolved_field *ref,
2330 classinfo *referer, methodinfo *refmethod,
2333 constant_FMIref *fieldref;
2334 varinfo *instanceslot = NULL;
2337 typeinfo *tip = NULL;
2342 fieldref = ref->fieldref;
2345 #ifdef RESOLVE_VERBOSE
2346 printf("constrain_unresolved_field\n");
2347 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2348 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2349 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2350 /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2351 printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2352 printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2353 printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2355 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2358 switch (iptr[0].opc) {
2360 instanceslot = VAROP(iptr->s1);
2361 tip = &(VAROP(iptr->sx.s23.s2)->typeinfo);
2364 case ICMD_PUTFIELDCONST:
2365 instanceslot = VAROP(iptr->s1);
2368 case ICMD_PUTSTATIC:
2369 tip = &(VAROP(iptr->s1)->typeinfo);
2373 instanceslot = VAROP(iptr->s1);
2377 assert(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
2378 fd = fieldref->parseddesc.fd;
2381 /* record subtype constraints for the instance type, if any */
2385 /* The instanceslot must contain a reference to a non-array type */
2386 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
2387 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
2390 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
2391 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
2395 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2396 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2398 /* The instruction writes a field in an uninitialized object. */
2399 /* This is only allowed when a field of an uninitialized 'this' object is */
2400 /* written inside an initialization method */
2402 classinfo *initclass;
2403 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2406 exceptions_throw_verifyerror(refmethod,"accessing field of uninitialized object");
2409 /* XXX check that class of field == refmethod->class */
2410 initclass = refmethod->class; /* XXX classrefs */
2411 assert(initclass->state & CLASS_LOADED);
2412 assert(initclass->state & CLASS_LINKED);
2414 typeinfo_init_classinfo(&tinfo,initclass);
2418 insttip = &(instanceslot->typeinfo);
2420 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2421 &(ref->instancetypes),insttip, FIELDREF_CLASSNAME(fieldref)))
2425 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2428 /* record subtype constraints for the value type, if any */
2430 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2432 /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
2434 if (iptr->sx.val.anyptr) {
2435 assert(class_java_lang_String);
2436 assert(class_java_lang_String->state & CLASS_LOADED);
2437 assert(class_java_lang_String->state & CLASS_LINKED);
2438 typeinfo_init_classinfo(&tinfo,class_java_lang_String);
2441 TYPEINFO_INIT_NULLTYPE(tinfo);
2443 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2444 &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref->name))
2448 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2453 #endif /* ENABLE_VERIFIER */
2455 /* create_unresolved_method ****************************************************
2457 Create an unresolved_method struct for the given method invocation
2460 referer..........the class containing the reference
2461 refmethod........the method triggering the resolution (if any)
2462 iptr.............the INVOKE* instruction
2465 a pointer to a new unresolved_method struct, or
2466 NULL if an exception has been thrown
2468 *******************************************************************************/
2470 unresolved_method * create_unresolved_method(classinfo *referer,
2471 methodinfo *refmethod,
2474 unresolved_method *ref;
2475 constant_FMIref *methodref;
2478 methodref = iptr->sx.s23.s3.fmiref;
2480 staticmethod = (iptr->opc == ICMD_INVOKESTATIC);
2482 #ifdef RESOLVE_VERBOSE
2483 printf("create_unresolved_method\n");
2484 printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2485 printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2486 printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2487 /* printf(" class : ");utf_fprint_printable_ascii(stdout,methodref->p.classref->name);fputc('\n',stdout);*/
2488 printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2489 printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2490 /*printf(" opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2493 /* allocate params if necessary */
2494 if (!methodref->parseddesc.md->params)
2495 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2496 (staticmethod) ? ACC_STATIC : ACC_NONE))
2499 /* create the data structure */
2500 ref = NEW(unresolved_method);
2501 ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
2502 | ((iptr->opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
2503 ref->referermethod = refmethod;
2504 ref->methodref = methodref;
2505 ref->paramconstraints = NULL;
2506 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2511 /* constrain_unresolved_method *********************************************
2513 Record subtype constraints for the arguments of a method call.
2516 ref..............the unresolved_method structure of the call
2517 referer..........the class containing the reference
2518 refmethod........the method triggering the resolution (if any)
2519 iptr.............the INVOKE* instruction
2522 true.............everything ok
2523 false............an exception has been thrown
2525 *******************************************************************************/
2527 #ifdef ENABLE_VERIFIER
2528 bool constrain_unresolved_method(jitdata *jd,
2529 unresolved_method *ref,
2530 classinfo *referer, methodinfo *refmethod,
2533 constant_FMIref *methodref;
2534 constant_classref *instanceref;
2535 varinfo *instanceslot = NULL;
2544 methodref = ref->methodref;
2546 md = methodref->parseddesc.md;
2548 assert(md->params != NULL);
2550 /* XXX clean this up */
2551 instanceref = IS_FMIREF_RESOLVED(methodref)
2552 ? class_get_self_classref(methodref->p.method->class)
2553 : methodref->p.classref;
2555 #ifdef RESOLVE_VERBOSE
2556 printf("constrain_unresolved_method\n");
2557 printf(" referer: "); class_println(referer);
2558 printf(" rmethod: "); method_println(refmethod);
2559 printf(" mref : "); method_methodref_println(methodref);
2560 /*printf(" opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2563 if ((ref->flags & RESOLVE_STATIC) == 0) {
2564 /* find the instance slot under all the parameter slots on the stack */
2565 instanceslot = VAR(iptr->sx.s23.s2.args[0]);
2572 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
2574 /* record subtype constraints for the instance type, if any */
2578 assert(instanceslot->type == TYPE_ADR);
2580 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
2581 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2582 { /* XXX clean up */
2583 instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2584 classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
2585 : CLASSREF_OR_CLASSINFO(refmethod->class);
2587 if (!typeinfo_init_class(tip,initclass))
2591 tip = &(instanceslot->typeinfo);
2593 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2594 &(ref->instancetypes),tip,instanceref->name))
2598 /* record subtype constraints for the parameter types, if any */
2599 for (i=md->paramcount-1-instancecount; i>=0; --i) {
2600 param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2601 type = md->paramtypes[i+instancecount].type;
2604 assert(type == param->type);
2606 if (type == TYPE_ADR) {
2607 if (!ref->paramconstraints) {
2608 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2609 for (j=md->paramcount-1-instancecount; j>i; --j)
2610 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2612 assert(ref->paramconstraints);
2613 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2614 ref->paramconstraints + i,&(param->typeinfo),
2615 md->paramtypes[i+instancecount].classref->name))
2619 if (ref->paramconstraints)
2620 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2626 #endif /* ENABLE_VERIFIER */
2628 /******************************************************************************/
2629 /* FREEING MEMORY */
2630 /******************************************************************************/
2632 #ifdef ENABLE_VERIFIER
2633 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2636 classref_or_classinfo *p = list;
2638 /* this is silly. we *only* need to count the elements for MFREE */
2641 MFREE(list,classref_or_classinfo,(p - list));
2644 #endif /* ENABLE_VERIFIER */
2646 /* unresolved_class_free *******************************************************
2648 Free the memory used by an unresolved_class
2651 ref..............the unresolved_class
2653 *******************************************************************************/
2655 void unresolved_class_free(unresolved_class *ref)
2659 #ifdef ENABLE_VERIFIER
2660 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2662 FREE(ref,unresolved_class);
2665 /* unresolved_field_free *******************************************************
2667 Free the memory used by an unresolved_field
2670 ref..............the unresolved_field
2672 *******************************************************************************/
2674 void unresolved_field_free(unresolved_field *ref)
2678 #ifdef ENABLE_VERIFIER
2679 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2680 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2682 FREE(ref,unresolved_field);
2685 /* unresolved_method_free ******************************************************
2687 Free the memory used by an unresolved_method
2690 ref..............the unresolved_method
2692 *******************************************************************************/
2694 void unresolved_method_free(unresolved_method *ref)
2698 #ifdef ENABLE_VERIFIER
2699 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2700 if (ref->paramconstraints) {
2702 int count = ref->methodref->parseddesc.md->paramcount;
2704 for (i=0; i<count; ++i)
2705 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2706 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2709 FREE(ref,unresolved_method);
2712 /******************************************************************************/
2714 /******************************************************************************/
2716 #if !defined(NDEBUG)
2718 /* unresolved_subtype_set_debug_dump *******************************************
2720 Print debug info for unresolved_subtype_set to stream
2723 stset............the unresolved_subtype_set
2724 file.............the stream
2726 *******************************************************************************/
2728 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2730 classref_or_classinfo *p;
2732 if (SUBTYPESET_IS_EMPTY(*stset)) {
2733 fprintf(file," (empty)\n");
2736 p = stset->subtyperefs;
2737 for (;p->any; ++p) {
2738 if (IS_CLASSREF(*p)) {
2739 fprintf(file," ref: ");
2740 utf_fprint_printable_ascii(file,p->ref->name);
2743 fprintf(file," cls: ");
2744 utf_fprint_printable_ascii(file,p->cls->name);
2751 /* unresolved_class_debug_dump *************************************************
2753 Print debug info for unresolved_class to stream
2756 ref..............the unresolved_class
2757 file.............the stream
2759 *******************************************************************************/
2761 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2763 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2765 fprintf(file," referer : ");
2766 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2767 fprintf(file," refmethod : ");
2768 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2769 fprintf(file," refmethodd: ");
2770 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2771 fprintf(file," classname : ");
2772 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2773 fprintf(file," subtypeconstraints:\n");
2774 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2778 /* unresolved_field_debug_dump *************************************************
2780 Print debug info for unresolved_field to stream
2783 ref..............the unresolved_field
2784 file.............the stream
2786 *******************************************************************************/
2788 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
2790 fprintf(file,"unresolved_field(%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,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
2800 fprintf(file," name : ");
2801 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
2802 fprintf(file," descriptor: ");
2803 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
2804 fprintf(file," parseddesc: ");
2805 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); 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," valueconstraints:\n");
2810 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
2814 /* unresolved_method_debug_dump ************************************************
2816 Print debug info for unresolved_method to stream
2819 ref..............the unresolved_method
2820 file.............the stream
2822 *******************************************************************************/
2824 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
2828 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
2830 fprintf(file," referer : ");
2831 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
2832 fprintf(file," refmethod : ");
2833 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2834 fprintf(file," refmethodd: ");
2835 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2836 fprintf(file," classname : ");
2837 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
2838 fprintf(file," name : ");
2839 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
2840 fprintf(file," descriptor: ");
2841 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
2842 fprintf(file," parseddesc: ");
2843 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
2844 fprintf(file," flags : %04x\n",ref->flags);
2845 fprintf(file," instancetypes:\n");
2846 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
2847 fprintf(file," paramconstraints:\n");
2848 if (ref->paramconstraints) {
2849 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
2850 fprintf(file," param %d:\n",i);
2851 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
2855 fprintf(file," (empty)\n");
2859 #endif /* !defined(NDEBUG) */
2862 * These are local overrides for various environment variables in Emacs.
2863 * Please do not remove this and leave it at the end of the file, where
2864 * Emacs will automagically detect them.
2865 * ---------------------------------------------------------------------
2868 * indent-tabs-mode: t
2872 * vim:noexpandtab:sw=4:ts=4: