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 5166 2006-07-21 10:09:33Z twisti $
40 #include "mm/memory.h"
41 #include "vm/resolve.h"
42 #include "vm/access.h"
43 #include "vm/classcache.h"
44 #include "vm/descriptor.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/linker.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/stringlocal.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/verify/typeinfo.h"
55 /******************************************************************************/
57 /******************************************************************************/
59 /*#define RESOLVE_VERBOSE*/
61 /******************************************************************************/
62 /* CLASS RESOLUTION */
63 /******************************************************************************/
65 /* resolve_class_from_name *****************************************************
67 Resolve a symbolic class reference
70 referer..........the class containing the reference
71 refmethod........the method from which resolution was triggered
72 (may be NULL if not applicable)
73 classname........class name to resolve
74 mode.............mode of resolution:
75 resolveLazy...only resolve if it does not
76 require loading classes
77 resolveEager..load classes if necessary
78 checkaccess......if true, access rights to the class are checked
79 link.............if true, guarantee that the returned class, if any,
83 *result..........set to result of resolution, or to NULL if
84 the reference has not been resolved
85 In the case of an exception, *result is
86 guaranteed to be set to NULL.
89 true.............everything ok
90 (*result may still be NULL for resolveLazy)
91 false............an exception has been thrown
94 The returned class is *not* guaranteed to be linked!
95 (It is guaranteed to be loaded, though.)
97 *******************************************************************************/
99 bool resolve_class_from_name(classinfo *referer,
100 methodinfo *refmethod,
107 classinfo *cls = NULL;
114 assert(mode == resolveLazy || mode == resolveEager);
118 #ifdef RESOLVE_VERBOSE
119 fprintf(stderr,"resolve_class_from_name(");
120 utf_fprint_printable_ascii(stderr,referer->name);
121 fprintf(stderr,",%p,",referer->classloader);
122 utf_fprint_printable_ascii(stderr,classname);
123 fprintf(stderr,",%d,%d)\n",(int)checkaccess,(int)link);
126 /* lookup if this class has already been loaded */
128 cls = classcache_lookup(referer->classloader, classname);
130 #ifdef RESOLVE_VERBOSE
131 fprintf(stderr," lookup result: %p\n",(void*)cls);
135 /* resolve array types */
137 if (classname->text[0] == '[') {
138 utf_ptr = classname->text + 1;
139 len = classname->blength - 1;
141 /* classname is an array type name */
149 /* the component type is a reference type */
150 /* resolve the component type */
151 if (!resolve_class_from_name(referer,refmethod,
152 utf_new(utf_ptr,len),
153 mode,checkaccess,link,&cls))
154 return false; /* exception */
156 assert(mode == resolveLazy);
157 return true; /* be lazy */
159 /* create the array class */
160 cls = class_array_of(cls,false);
162 return false; /* exception */
166 /* the class has not been loaded, yet */
167 if (mode == resolveLazy)
168 return true; /* be lazy */
171 #ifdef RESOLVE_VERBOSE
172 fprintf(stderr," loading...\n");
177 if (!(cls = load_class_from_classloader(classname,
178 referer->classloader)))
179 return false; /* exception */
183 /* the class is now loaded */
185 assert(cls->state & CLASS_LOADED);
187 #ifdef RESOLVE_VERBOSE
188 fprintf(stderr," checking access rights...\n");
191 /* check access rights of referer to refered class */
192 if (checkaccess && !access_is_accessible_class(referer,cls)) {
196 msglen = utf_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 fprintf(stderr," success.\n");
225 /* resolve_classref ************************************************************
227 Resolve a symbolic class reference
230 refmethod........the method from which resolution was triggered
231 (may be NULL if not applicable)
232 ref..............class reference
233 mode.............mode of resolution:
234 resolveLazy...only resolve if it does not
235 require loading classes
236 resolveEager..load classes if necessary
237 checkaccess......if true, access rights to the class are checked
238 link.............if true, guarantee that the returned class, if any,
242 *result..........set to result of resolution, or to NULL if
243 the reference has not been resolved
244 In the case of an exception, *result is
245 guaranteed to be set to NULL.
248 true.............everything ok
249 (*result may still be NULL for resolveLazy)
250 false............an exception has been thrown
252 *******************************************************************************/
254 bool resolve_classref(methodinfo *refmethod,
255 constant_classref *ref,
261 return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
264 /* resolve_classref_or_classinfo ***********************************************
266 Resolve a symbolic class reference if necessary
269 refmethod........the method from which resolution was triggered
270 (may be NULL if not applicable)
271 cls..............class reference or classinfo
272 mode.............mode of resolution:
273 resolveLazy...only resolve if it does not
274 require loading classes
275 resolveEager..load classes if necessary
276 checkaccess......if true, access rights to the class are checked
277 link.............if true, guarantee that the returned class, if any,
281 *result..........set to result of resolution, or to NULL if
282 the reference has not been resolved
283 In the case of an exception, *result is
284 guaranteed to be set to NULL.
287 true.............everything ok
288 (*result may still be NULL for resolveLazy)
289 false............an exception has been thrown
291 *******************************************************************************/
293 bool resolve_classref_or_classinfo(methodinfo *refmethod,
294 classref_or_classinfo cls,
303 assert(mode == resolveEager || mode == resolveLazy);
306 #ifdef RESOLVE_VERBOSE
307 fprintf(stderr,"resolve_classref_or_classinfo(");
308 utf_fprint_printable_ascii(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
309 fprintf(stderr,",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
314 if (IS_CLASSREF(cls)) {
315 /* we must resolve this reference */
317 if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
318 mode, checkaccess, link, &c))
319 goto return_exception;
322 /* cls has already been resolved */
324 assert(c->state & CLASS_LOADED);
326 assert(c || (mode == resolveLazy));
329 return true; /* be lazy */
332 assert(c->state & CLASS_LOADED);
335 if (!(c->state & CLASS_LINKED))
337 goto return_exception;
339 assert(c->state & CLASS_LINKED);
352 /* resolve_class_from_typedesc *************************************************
354 Return a classinfo * for the given type descriptor
357 d................type descriptor
358 checkaccess......if true, access rights to the class are checked
359 link.............if true, guarantee that the returned class, if any,
362 *result..........set to result of resolution, or to NULL if
363 the reference has not been resolved
364 In the case of an exception, *result is
365 guaranteed to be set to NULL.
368 true.............everything ok
369 false............an exception has been thrown
372 This function always resolves eagerly.
374 *******************************************************************************/
376 bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
385 #ifdef RESOLVE_VERBOSE
386 fprintf(stderr,"resolve_class_from_typedesc(");
387 descriptor_debug_print_typedesc(stderr,d);
388 fprintf(stderr,",%i,%i)\n",(int)checkaccess,(int)link);
391 if (d->type == TYPE_ADR) {
392 /* a reference type */
394 if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
395 resolveEager,checkaccess,link,&cls))
396 return false; /* exception */
399 /* a primitive type */
400 cls = primitivetype_table[d->decltype].class_primitive;
401 assert(cls->state & CLASS_LOADED);
402 if (!(cls->state & CLASS_LINKED))
403 if (!link_class(cls))
404 return false; /* exception */
407 assert(cls->state & CLASS_LOADED);
408 assert(!link || (cls->state & CLASS_LINKED));
410 #ifdef RESOLVE_VERBOSE
411 fprintf(stderr," result = ");utf_fprint_printable_ascii(stderr,cls->name);fprintf(stderr,"\n");
418 /******************************************************************************/
419 /* SUBTYPE SET CHECKS */
420 /******************************************************************************/
422 /* resolve_subtype_check *******************************************************
424 Resolve the given types lazily and perform a subtype check
427 refmethod........the method triggering the resolution
428 subtype..........checked to be a subtype of supertype
429 supertype........the super type to check agaings
430 mode.............mode of resolution:
431 resolveLazy...only resolve if it does not
432 require loading classes
433 resolveEager..load classes if necessary
434 error............which type of exception to throw if
435 the test fails. May be:
436 resolveLinkageError, or
437 resolveIllegalAccessError
438 IMPORTANT: If error==resolveIllegalAccessError,
439 then array types are not checked.
442 resolveSucceeded.....the check succeeded
443 resolveDeferred......the check could not be performed due to
444 unresolved types. (This can only happen for
445 mode == resolveLazy.)
446 resolveFailed........the check failed, an exception has been thrown.
449 The types are resolved first, so any
450 exception which may occurr during resolution may
451 be thrown by this function.
453 *******************************************************************************/
455 #if defined(ENABLE_VERIFIER)
456 static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
457 classref_or_classinfo subtype,
458 classref_or_classinfo supertype,
468 assert(supertype.any);
469 assert(mode == resolveLazy || mode == resolveEager);
470 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
472 /* resolve the subtype */
474 if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
475 /* the subclass could not be resolved. therefore we are sure that */
476 /* no instances of this subclass will ever exist -> skip this test */
477 /* XXX this assumes that class loading has invariant results (as in JVM spec) */
478 *exceptionptr = NULL;
479 return resolveSucceeded;
482 return resolveDeferred; /* be lazy */
484 assert(subclass->state & CLASS_LINKED);
486 /* do not check access to protected members of arrays */
488 if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
489 return resolveSucceeded;
492 /* perform the subtype check */
494 typeinfo_init_classinfo(&subti,subclass);
496 r = typeinfo_is_assignable_to_class(&subti,supertype);
497 if (r == typecheck_FAIL)
498 return resolveFailed; /* failed, exception is already set */
500 if (r == typecheck_MAYBE) {
501 assert(IS_CLASSREF(supertype));
502 if (mode == resolveEager) {
503 if (!resolve_classref_or_classinfo(refmethod,supertype,
504 resolveEager,false,true,
507 return resolveFailed;
509 assert(supertype.cls);
513 return resolveDeferred; /* be lazy */
517 /* sub class relationship is false */
522 msglen = utf_bytes(subclass->name) + utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype)) + 200;
523 message = MNEW(char, msglen);
524 strcpy(message, (error == resolveIllegalAccessError) ?
525 "illegal access to protected member ("
526 : "subtype constraint violated (");
527 utf_cat_classname(message, subclass->name);
528 strcat(message, " is not a subclass of ");
529 utf_cat_classname(message, CLASSREF_OR_CLASSINFO_NAME(supertype));
530 strcat(message, ")");
531 if (error == resolveIllegalAccessError)
532 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
534 *exceptionptr = exceptions_new_linkageerror(message, NULL);
535 MFREE(message, char, msglen);
536 return resolveFailed; /* exception */
541 return resolveSucceeded;
543 #endif /* defined(ENABLE_VERIFIER) */
545 /* resolve_lazy_subtype_checks *************************************************
547 Resolve the types to check lazily and perform subtype checks
550 refmethod........the method triggering the resolution
551 subtinfo.........the typeinfo containing the subtypes
552 supertype........the supertype to test againgst
553 mode.............mode of resolution:
554 resolveLazy...only resolve if it does not
555 require loading classes
556 resolveEager..load classes if necessary
557 error............which type of exception to throw if
558 the test fails. May be:
559 resolveLinkageError, or
560 resolveIllegalAccessError
561 IMPORTANT: If error==resolveIllegalAccessError,
562 then array types in the set are skipped.
565 resolveSucceeded.....the check succeeded
566 resolveDeferred......the check could not be performed due to
568 resolveFailed........the check failed, an exception has been thrown.
571 The references in the set are resolved first, so any
572 exception which may occurr during resolution may
573 be thrown by this function.
575 *******************************************************************************/
577 #if defined(ENABLE_VERIFIER)
578 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
580 classref_or_classinfo supertype,
585 resolve_result_t result;
589 assert(supertype.any);
590 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
592 /* returnAddresses are illegal here */
594 if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
595 exceptions_throw_verifyerror(refmethod,
596 "Invalid use of returnAddress");
597 return resolveFailed;
600 /* uninitialized objects are illegal here */
602 if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
603 exceptions_throw_verifyerror(refmethod,
604 "Invalid use of uninitialized object");
605 return resolveFailed;
608 /* the nulltype is always assignable */
610 if (TYPEINFO_IS_NULLTYPE(*subtinfo))
611 return resolveSucceeded;
613 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
615 if (supertype.cls == class_java_lang_Object
616 || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
617 && refmethod->class->classloader == NULL))
619 return resolveSucceeded;
622 if (subtinfo->merged) {
624 /* for a merged type we have to do a series of checks */
626 count = subtinfo->merged->count;
627 for (i=0; i<count; ++i) {
628 classref_or_classinfo c = subtinfo->merged->list[i];
629 if (subtinfo->dimension > 0) {
630 /* a merge of array types */
631 /* the merged list contains the possible _element_ types, */
632 /* so we have to create array types with these elements. */
633 if (IS_CLASSREF(c)) {
634 c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
637 c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
641 /* do the subtype check against the type c */
643 result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
644 if (result != resolveSucceeded)
650 /* a single type, this is the common case, hopefully */
652 if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
653 == CLASSREF_OR_CLASSINFO_NAME(supertype))
655 /* the class names are the same */
656 /* equality is guaranteed by the loading constraints */
657 return resolveSucceeded;
661 /* some other type name, try to perform the check lazily */
663 return resolve_subtype_check(refmethod,
664 subtinfo->typeclass,supertype,
671 return resolveSucceeded;
673 #endif /* defined(ENABLE_VERIFIER) */
675 /* resolve_and_check_subtype_set ***********************************************
677 Resolve the references in the given set and test subtype relationships
680 refmethod........the method triggering the resolution
681 ref..............a set of class/interface references
683 typeref..........the type to test against the set
684 mode.............mode of resolution:
685 resolveLazy...only resolve if it does not
686 require loading classes
687 resolveEager..load classes if necessary
688 error............which type of exception to throw if
689 the test fails. May be:
690 resolveLinkageError, or
691 resolveIllegalAccessError
692 IMPORTANT: If error==resolveIllegalAccessError,
693 then array types in the set are skipped.
696 resolveSucceeded.....the check succeeded
697 resolveDeferred......the check could not be performed due to
698 unresolved types. (This can only happen if
699 mode == resolveLazy.)
700 resolveFailed........the check failed, an exception has been thrown.
703 The references in the set are resolved first, so any
704 exception which may occurr during resolution may
705 be thrown by this function.
707 *******************************************************************************/
709 #if defined(ENABLE_VERIFIER)
710 static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
711 unresolved_subtype_set *ref,
712 classref_or_classinfo typeref,
716 classref_or_classinfo *setp;
717 typecheck_result checkresult;
722 assert(mode == resolveLazy || mode == resolveEager);
723 assert(error == resolveLinkageError || error == resolveIllegalAccessError);
725 setp = ref->subtyperefs;
727 /* an empty set of tests always succeeds */
728 if (!setp || !setp->any) {
729 return resolveSucceeded;
732 /* first resolve the type if necessary */
733 if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
734 return resolveFailed; /* exception */
736 return resolveDeferred; /* be lazy */
738 assert(typeref.cls->state & CLASS_LINKED);
740 /* iterate over the set members */
742 for (; setp->any; ++setp) {
743 checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
744 if (checkresult != resolveSucceeded)
749 return resolveSucceeded;
751 #endif /* defined(ENABLE_VERIFIER) */
753 /******************************************************************************/
754 /* CLASS RESOLUTION */
755 /******************************************************************************/
757 /* resolve_class ***************************************************************
759 Resolve an unresolved class reference. The class is also linked.
762 ref..............struct containing the reference
763 mode.............mode of resolution:
764 resolveLazy...only resolve if it does not
765 require loading classes
766 resolveEager..load classes if necessary
767 checkaccess......if true, access rights to the class are checked
770 *result..........set to the result of resolution, or to NULL if
771 the reference has not been resolved
772 In the case of an exception, *result is
773 guaranteed to be set to NULL.
776 true.............everything ok
777 (*result may still be NULL for resolveLazy)
778 false............an exception has been thrown
780 *******************************************************************************/
782 #ifdef ENABLE_VERIFIER
783 bool resolve_class(unresolved_class *ref,
789 resolve_result_t checkresult;
793 assert(mode == resolveLazy || mode == resolveEager);
797 #ifdef RESOLVE_VERBOSE
798 unresolved_class_debug_dump(ref,stderr);
801 /* first we must resolve the class */
802 if (!resolve_classref(ref->referermethod,
803 ref->classref,mode,checkaccess,true,&cls))
805 /* the class reference could not be resolved */
806 return false; /* exception */
809 return true; /* be lazy */
812 assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
814 /* now we check the subtype constraints */
816 checkresult = resolve_and_check_subtype_set(ref->referermethod,
817 &(ref->subtypeconstraints),
818 CLASSREF_OR_CLASSINFO(cls),
820 resolveLinkageError);
821 if (checkresult != resolveSucceeded)
822 return (bool) checkresult;
828 #endif /* ENABLE_VERIFIER */
830 /* resolve_classref_eager ******************************************************
832 Resolve an unresolved class reference eagerly. The class is also linked and
833 access rights to the class are checked.
836 ref..............constant_classref to the class
839 classinfo * to the class, or
840 NULL if an exception has been thrown
842 *******************************************************************************/
844 classinfo * resolve_classref_eager(constant_classref *ref)
848 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
854 /* resolve_classref_eager_nonabstract ******************************************
856 Resolve an unresolved class reference eagerly. The class is also linked and
857 access rights to the class are checked. A check is performed that the class
861 ref..............constant_classref to the class
864 classinfo * to the class, or
865 NULL if an exception has been thrown
867 *******************************************************************************/
869 classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
873 if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
876 /* ensure that the class is not abstract */
878 if (c->flags & ACC_ABSTRACT) {
879 exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
886 /* resolve_class_eager *********************************************************
888 Resolve an unresolved class reference eagerly. The class is also linked and
889 access rights to the class are checked.
892 ref..............struct containing the reference
895 classinfo * to the class, or
896 NULL if an exception has been thrown
898 *******************************************************************************/
900 #ifdef ENABLE_VERIFIER
901 classinfo * resolve_class_eager(unresolved_class *ref)
905 if (!resolve_class(ref,resolveEager,true,&c))
910 #endif /* ENABLE_VERIFIER */
912 /******************************************************************************/
913 /* FIELD RESOLUTION */
914 /******************************************************************************/
916 /* resolve_field_verifier_checks ***********************************************
918 Do the verifier checks necessary after field has been resolved.
921 refmethod........the method containing the reference
922 fieldref.........the field reference
923 container........the class where the field was found
924 fi...............the fieldinfo of the resolved field
925 opc..............opcode of the {GET,PUT}{STATIC,FIELD} instruction
928 resolveSucceeded....everything ok
929 resolveDeferred.....tests could not be done, have been deferred
930 resolveFailed.......exception has been thrown
932 *******************************************************************************/
934 #if defined(ENABLE_VERIFIER)
935 resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
936 constant_FMIref *fieldref,
937 classinfo *container,
944 resolve_result_t result;
945 bool isstatic = false;
947 stackelement *instanceslot = NULL;
948 stackelement *valueslot = NULL;
949 constant_classref *fieldtyperef;
956 /* get the classinfos and the field type */
958 referer = refmethod->class;
961 declarer = fi->class;
963 assert(referer->state & CLASS_LINKED);
965 fieldtyperef = fieldref->parseddesc.fd->classref;
967 /* get opcode dependent values */
973 valueslot = curstack;
974 instanceslot = curstack->prev;
978 case ICMD_PUTFIELDCONST:
980 instanceslot = curstack;
986 valueslot = curstack;
989 case ICMD_PUTSTATICCONST:
995 instanceslot = curstack;
1006 #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1009 if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1010 /* a static field is accessed via an instance, or vice versa */
1012 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1013 (fi->flags & ACC_STATIC) ? "static field accessed via instance"
1014 : "instance field accessed without instance");
1015 return resolveFailed;
1018 /* check access rights */
1020 if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1024 msglen = utf_bytes(declarer->name) + utf_bytes(fi->name) + utf_bytes(referer->name) + 100;
1025 message = MNEW(char, msglen);
1026 strcpy(message, "field is not accessible (");
1027 utf_cat_classname(message, declarer->name);
1028 strcat(message, ".");
1029 utf_cat(message, fi->name);
1030 strcat(message, " from ");
1031 utf_cat_classname(message, referer->name);
1032 strcat(message, ")");
1033 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1034 MFREE(message,char,msglen);
1035 return resolveFailed; /* exception */
1038 /* for non-static methods we have to check the constraints on the */
1045 /* The instanceslot must contain a reference to a non-array type */
1047 assert(instanceslot->type == TYPE_ADR); /* checked earlier */
1049 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
1050 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1051 return resolveFailed;
1053 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
1054 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1055 return resolveFailed;
1058 if (isput && TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1060 /* The instruction writes a field in an uninitialized object. */
1061 /* This is only allowed when a field of an uninitialized 'this' object is */
1062 /* written inside an initialization method */
1064 classinfo *initclass;
1065 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1068 exceptions_throw_verifyerror(refmethod,"accessing field of uninitialized object");
1069 return resolveFailed;
1072 /* XXX check that class of field == refmethod->class */
1073 initclass = referer; /* XXX classrefs */
1074 assert(initclass->state & CLASS_LINKED);
1076 typeinfo_init_classinfo(&tinfo,initclass);
1080 insttip = &(instanceslot->typeinfo);
1083 result = resolve_lazy_subtype_checks(refmethod,
1085 CLASSREF_OR_CLASSINFO(container),
1086 resolveLinkageError);
1087 if (result != resolveSucceeded)
1090 /* check protected access */
1092 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1094 result = resolve_lazy_subtype_checks(refmethod,
1095 &(instanceslot->typeinfo),
1096 CLASSREF_OR_CLASSINFO(referer),
1097 resolveIllegalAccessError);
1098 if (result != resolveSucceeded)
1104 /* for PUT* instructions we have to check the constraints on the value type */
1106 if (valueslot && valueslot->type == TYPE_ADR) {
1107 assert(fieldtyperef);
1109 /* check subtype constraints */
1110 result = resolve_lazy_subtype_checks(refmethod,
1111 &(valueslot->typeinfo),
1112 CLASSREF_OR_CLASSINFO(fieldtyperef),
1113 resolveLinkageError);
1115 if (result != resolveSucceeded)
1119 /* impose loading constraint on field type */
1121 if (fi->type == TYPE_ADR) {
1122 assert(fieldtyperef);
1123 if (!classcache_add_constraint(declarer->classloader,
1124 referer->classloader,
1125 fieldtyperef->name))
1126 return resolveFailed;
1129 /* XXX impose loading constraing on instance? */
1132 return resolveSucceeded;
1134 #endif /* defined(ENABLE_VERIFIER) */
1136 /* resolve_field_lazy **********************************************************
1138 Resolve an unresolved field reference lazily
1141 iptr.............instruction containing the field reference
1142 curstack.........instack of the instruction
1143 refmethod........the referer method
1146 resolveSucceeded.....the reference has been resolved
1147 resolveDeferred......the resolving could not be performed lazily
1148 resolveFailed........resolving failed, an exception has been thrown.
1150 *******************************************************************************/
1152 resolve_result_t new_resolve_field_lazy(new_instruction *iptr,
1154 methodinfo *refmethod)
1157 classinfo *container;
1159 constant_FMIref *fieldref;
1160 resolve_result_t result;
1165 /* the class containing the reference */
1167 referer = refmethod->class;
1170 /* get the field reference */
1172 NEW_INSTRUCTION_GET_FIELDREF(iptr, fieldref);
1174 /* check if the field itself is already resolved */
1176 if (IS_FMIREF_RESOLVED(fieldref)) {
1177 fi = fieldref->p.field;
1178 container = fi->class;
1179 goto resolved_the_field;
1182 /* first we must resolve the class containg the field */
1184 /* XXX can/may lazyResolving trigger linking? */
1186 if (!resolve_class_from_name(referer, refmethod,
1187 fieldref->p.classref->name, resolveLazy, true, true, &container))
1189 /* the class reference could not be resolved */
1190 return resolveFailed; /* exception */
1193 return resolveDeferred; /* be lazy */
1195 assert(container->state & CLASS_LINKED);
1197 /* now we must find the declaration of the field in `container`
1198 * or one of its superclasses */
1200 fi = class_resolvefield(container,
1201 fieldref->name, fieldref->descriptor,
1204 /* The field does not exist. But since we were called lazily, */
1205 /* this error must not be reported now. (It will be reported */
1206 /* if eager resolving of this field is ever tried.) */
1208 *exceptionptr = NULL;
1209 return resolveDeferred; /* be lazy */
1212 /* cache the result of the resolution */
1214 fieldref->p.field = fi;
1218 #if defined(ENABLE_VERIFIER)
1220 result = resolve_field_verifier_checks(refmethod, fieldref, container,
1225 if (result != resolveSucceeded)
1228 #endif /* defined(ENABLE_VERIFIER) */
1231 return resolveSucceeded;
1234 resolve_result_t resolve_field_lazy(instruction *iptr,stackptr curstack,
1235 methodinfo *refmethod)
1238 classinfo *container;
1240 constant_FMIref *fieldref;
1241 resolve_result_t result;
1246 /* the class containing the reference */
1248 referer = refmethod->class;
1251 /* get the field reference */
1253 if (iptr->opc == ICMD_PUTFIELDCONST || iptr->opc == ICMD_PUTSTATICCONST)
1254 INSTRUCTION_GET_FIELDREF(iptr + 1,fieldref);
1256 INSTRUCTION_GET_FIELDREF(iptr,fieldref);
1258 /* check if the field itself is already resolved */
1260 if (IS_FMIREF_RESOLVED(fieldref)) {
1261 fi = fieldref->p.field;
1262 container = fi->class;
1263 goto resolved_the_field;
1266 /* first we must resolve the class containg the field */
1268 /* XXX can/may lazyResolving trigger linking? */
1270 if (!resolve_class_from_name(referer,refmethod,
1271 fieldref->p.classref->name,resolveLazy,true,true,&container))
1273 /* the class reference could not be resolved */
1274 return resolveFailed; /* exception */
1277 return resolveDeferred; /* be lazy */
1279 assert(container->state & CLASS_LINKED);
1281 /* now we must find the declaration of the field in `container`
1282 * or one of its superclasses */
1284 fi = class_resolvefield(container,
1285 fieldref->name,fieldref->descriptor,
1288 /* The field does not exist. But since we were called lazily, */
1289 /* this error must not be reported now. (It will be reported */
1290 /* if eager resolving of this field is ever tried.) */
1292 *exceptionptr = NULL;
1293 return resolveDeferred; /* be lazy */
1296 /* cache the result of the resolution */
1298 fieldref->p.field = fi;
1302 #if defined(ENABLE_VERIFIER)
1304 result = resolve_field_verifier_checks(refmethod,fieldref,container,
1309 if (result != resolveSucceeded)
1312 #endif /* defined(ENABLE_VERIFIER) */
1315 return resolveSucceeded;
1318 /* resolve_field ***************************************************************
1320 Resolve an unresolved field reference
1323 ref..............struct containing the reference
1324 mode.............mode of resolution:
1325 resolveLazy...only resolve if it does not
1326 require loading classes
1327 resolveEager..load classes if necessary
1330 *result..........set to the result of resolution, or to NULL if
1331 the reference has not been resolved
1332 In the case of an exception, *result is
1333 guaranteed to be set to NULL.
1336 true.............everything ok
1337 (*result may still be NULL for resolveLazy)
1338 false............an exception has been thrown
1340 *******************************************************************************/
1342 bool resolve_field(unresolved_field *ref,
1343 resolve_mode_t mode,
1347 classinfo *container;
1348 classinfo *declarer;
1349 constant_classref *fieldtyperef;
1351 resolve_result_t checkresult;
1355 assert(mode == resolveLazy || mode == resolveEager);
1359 #ifdef RESOLVE_VERBOSE
1360 unresolved_field_debug_dump(ref,stderr);
1363 /* the class containing the reference */
1365 referer = ref->referermethod->class;
1368 /* check if the field itself is already resolved */
1369 if (IS_FMIREF_RESOLVED(ref->fieldref)) {
1370 fi = ref->fieldref->p.field;
1371 container = fi->class;
1372 goto resolved_the_field;
1375 /* first we must resolve the class containg the field */
1376 if (!resolve_class_from_name(referer,ref->referermethod,
1377 ref->fieldref->p.classref->name,mode,true,true,&container))
1379 /* the class reference could not be resolved */
1380 return false; /* exception */
1383 return true; /* be lazy */
1386 assert(container->state & CLASS_LOADED);
1387 assert(container->state & CLASS_LINKED);
1389 /* now we must find the declaration of the field in `container`
1390 * or one of its superclasses */
1392 #ifdef RESOLVE_VERBOSE
1393 fprintf(stderr," resolving field in class...\n");
1396 fi = class_resolvefield(container,
1397 ref->fieldref->name,ref->fieldref->descriptor,
1400 if (mode == resolveLazy) {
1401 /* The field does not exist. But since we were called lazily, */
1402 /* this error must not be reported now. (It will be reported */
1403 /* if eager resolving of this field is ever tried.) */
1405 *exceptionptr = NULL;
1406 return true; /* be lazy */
1409 return false; /* exception */
1412 /* cache the result of the resolution */
1413 ref->fieldref->p.field = fi;
1417 #ifdef ENABLE_VERIFIER
1419 checkresult = resolve_field_verifier_checks(ref->referermethod,
1423 /* XXX pass NULL instruction * */
1424 (ref->flags & RESOLVE_STATIC) ? ICMD_GETSTATIC : ICMD_GETFIELD,
1427 if (checkresult != resolveSucceeded)
1428 return (bool) checkresult;
1430 declarer = fi->class;
1432 assert(declarer->state & CLASS_LOADED);
1433 assert(declarer->state & CLASS_LINKED);
1435 /* for non-static accesses we have to check the constraints on the */
1438 if (!(ref->flags & RESOLVE_STATIC)) {
1439 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1440 &(ref->instancetypes),
1441 CLASSREF_OR_CLASSINFO(container),
1442 mode, resolveLinkageError);
1443 if (checkresult != resolveSucceeded)
1444 return (bool) checkresult;
1447 fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1449 /* for PUT* instructions we have to check the constraints on the value type */
1450 if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1451 assert(fieldtyperef);
1452 if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1453 /* check subtype constraints */
1454 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1455 &(ref->valueconstraints),
1456 CLASSREF_OR_CLASSINFO(fieldtyperef),
1457 mode, resolveLinkageError);
1458 if (checkresult != resolveSucceeded)
1459 return (bool) checkresult;
1463 /* check protected access */
1464 if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1465 checkresult = resolve_and_check_subtype_set(ref->referermethod,
1466 &(ref->instancetypes),
1467 CLASSREF_OR_CLASSINFO(referer),
1469 resolveIllegalAccessError);
1470 if (checkresult != resolveSucceeded)
1471 return (bool) checkresult;
1475 #endif /* ENABLE_VERIFIER */
1483 /* resolve_field_eager *********************************************************
1485 Resolve an unresolved field reference eagerly.
1488 ref..............struct containing the reference
1491 fieldinfo * to the field, or
1492 NULL if an exception has been thrown
1494 *******************************************************************************/
1496 fieldinfo * resolve_field_eager(unresolved_field *ref)
1500 if (!resolve_field(ref,resolveEager,&fi))
1506 /******************************************************************************/
1507 /* METHOD RESOLUTION */
1508 /******************************************************************************/
1510 /* resolve_method_invokespecial_lookup *****************************************
1512 Do the special lookup for methods invoked by INVOKESPECIAL
1515 refmethod........the method containing the reference
1516 mi...............the methodinfo of the resolved method
1519 a methodinfo *...the result of the lookup,
1520 NULL.............an exception has been thrown
1522 *******************************************************************************/
1524 methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1527 classinfo *declarer;
1533 /* get referer and declarer classes */
1535 referer = refmethod->class;
1538 declarer = mi->class;
1540 assert(referer->state & CLASS_LINKED);
1542 /* checks for INVOKESPECIAL: */
1543 /* for <init> and methods of the current class we don't need any */
1544 /* special checks. Otherwise we must verify that the called method */
1545 /* belongs to a super class of the current class */
1547 if ((referer != declarer) && (mi->name != utf_init)) {
1548 /* check that declarer is a super class of the current class */
1550 if (!class_issubclass(referer,declarer)) {
1551 exceptions_throw_verifyerror(refmethod,
1552 "INVOKESPECIAL calling non-super class method");
1556 /* if the referer has ACC_SUPER set, we must do the special */
1557 /* lookup starting with the direct super class of referer */
1559 if ((referer->flags & ACC_SUPER) != 0) {
1560 mi = class_resolvemethod(referer->super.cls,
1565 /* the spec calls for an AbstractMethodError in this case */
1566 exceptions_throw_abstractmethoderror();
1576 /* resolve_method_verifier_checks **********************************************
1578 Do the verifier checks necessary after a method has been resolved.
1581 refmethod........the method containing the reference
1582 methodref........the method reference
1583 container........the class where the method was found
1584 mi...............the methodinfo of the resolved method
1585 invokestatic.....true if the method is invoked by INVOKESTATIC
1588 resolveSucceeded....everything ok
1589 resolveDeferred.....tests could not be done, have been deferred
1590 resolveFailed.......exception has been thrown
1592 *******************************************************************************/
1594 #if defined(ENABLE_VERIFIER)
1595 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1596 constant_FMIref *methodref,
1597 classinfo *container,
1603 classinfo *declarer;
1605 resolve_result_t result;
1607 typedesc *paramtypes;
1609 stackelement *instanceslot = NULL;
1610 stackelement *param;
1620 #ifdef RESOLVE_VERBOSE
1621 fprintf(stderr,"resolve_method_verifier_checks\n");
1622 fprintf(stderr," flags: %02x\n",mi->flags);
1625 /* get the classinfos and the method descriptor */
1627 referer = refmethod->class;
1630 declarer = mi->class;
1632 assert(referer->state & CLASS_LINKED);
1634 md = methodref->parseddesc.md;
1638 instancecount = (invokestatic) ? 0 : 1;
1642 if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1643 /* a static method is accessed via an instance, or vice versa */
1645 new_exception_message(string_java_lang_IncompatibleClassChangeError,
1646 (mi->flags & ACC_STATIC) ? "static method called via instance"
1647 : "instance method called without instance");
1648 return resolveFailed;
1651 /* check access rights */
1653 if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1657 /* XXX clean this up. this should be in exceptions.c */
1658 msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
1659 utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
1660 message = MNEW(char, msglen);
1661 strcpy(message, "method is not accessible (");
1662 utf_cat_classname(message, declarer->name);
1663 strcat(message, ".");
1664 utf_cat(message, mi->name);
1665 utf_cat(message, mi->descriptor);
1666 strcat(message," from ");
1667 utf_cat_classname(message, referer->name);
1668 strcat(message,")");
1669 *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
1670 MFREE(message, char, msglen);
1671 return resolveFailed; /* exception */
1675 /* for non-static methods we have to check the constraints on the */
1678 if (!invokestatic) {
1679 /* find the instance slot under all the parameter slots on the stack */
1680 instanceslot = curstack;
1681 for (i=1; i<md->paramcount; ++i)
1682 instanceslot = instanceslot->prev;
1685 assert((instanceslot && instancecount == 1) || invokestatic);
1687 /* record subtype constraints for the instance type, if any */
1691 assert(instanceslot->type == TYPE_ADR);
1693 if (invokespecial &&
1694 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
1695 { /* XXX clean up */
1696 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
1697 classref_or_classinfo initclass = (ins) ? ICMD_ACONST_CLASSREF_OR_CLASSINFO(ins-1)
1698 : CLASSREF_OR_CLASSINFO(refmethod->class);
1700 if (!typeinfo_init_class(tip,initclass))
1704 tip = &(instanceslot->typeinfo);
1707 result = resolve_lazy_subtype_checks(refmethod,
1709 CLASSREF_OR_CLASSINFO(container),
1710 resolveLinkageError);
1711 if (result != resolveSucceeded)
1714 /* check protected access */
1716 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1718 result = resolve_lazy_subtype_checks(refmethod,
1720 CLASSREF_OR_CLASSINFO(referer),
1721 resolveIllegalAccessError);
1722 if (result != resolveSucceeded)
1728 /* check subtype constraints for TYPE_ADR parameters */
1730 assert(md->paramcount == methodref->parseddesc.md->paramcount);
1731 paramtypes = md->paramtypes;
1734 for (i = md->paramcount-1-instancecount; i>=0; --i, param = param->prev) {
1735 type = md->paramtypes[i+instancecount].type;
1738 assert(type == param->type);
1740 if (type == TYPE_ADR) {
1741 result = resolve_lazy_subtype_checks(refmethod,
1743 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
1744 resolveLinkageError);
1745 if (result != resolveSucceeded)
1750 } /* if (curstack) */
1752 /* impose loading constraints on parameters (including instance) */
1754 paramtypes = md->paramtypes;
1756 for (i = 0; i < md->paramcount; i++) {
1757 if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1760 if (i < instancecount) {
1761 /* The type of the 'this' pointer is the class containing */
1762 /* the method definition. Since container is the same as, */
1763 /* or a subclass of declarer, we also constrain declarer */
1764 /* by transitivity of loading constraints. */
1765 name = container->name;
1768 name = paramtypes[i].classref->name;
1771 /* The caller (referer) and the callee (container) must agree */
1772 /* on the types of the parameters. */
1773 if (!classcache_add_constraint(referer->classloader,
1774 container->classloader, name))
1775 return resolveFailed; /* exception */
1779 /* impose loading constraint onto return type */
1781 if (md->returntype.type == TYPE_ADR) {
1782 /* The caller (referer) and the callee (container) must agree */
1783 /* on the return type. */
1784 if (!classcache_add_constraint(referer->classloader,container->classloader,
1785 md->returntype.classref->name))
1786 return resolveFailed; /* exception */
1790 return resolveSucceeded;
1792 #endif /* defined(ENABLE_VERIFIER) */
1794 /* resolve_method_lazy *********************************************************
1796 Resolve an unresolved method reference lazily
1799 iptr.............instruction containing the method reference
1800 curstack.........instack of the instruction
1801 refmethod........the referer method
1804 resolveSucceeded.....the reference has been resolved
1805 resolveDeferred......the resolving could not be performed lazily
1806 resolveFailed........resolving failed, an exception has been thrown.
1808 *******************************************************************************/
1810 resolve_result_t new_resolve_method_lazy(new_instruction *iptr,
1812 methodinfo *refmethod)
1815 classinfo *container;
1817 constant_FMIref *methodref;
1818 resolve_result_t result;
1823 #ifdef RESOLVE_VERBOSE
1824 fprintf(stderr,"resolve_method_lazy\n");
1827 /* the class containing the reference */
1829 referer = refmethod->class;
1832 /* the method reference */
1834 NEW_INSTRUCTION_GET_METHODREF(iptr, methodref);
1836 /* check if the method itself is already resolved */
1838 if (IS_FMIREF_RESOLVED(methodref)) {
1839 mi = methodref->p.method;
1840 container = mi->class;
1841 goto resolved_the_method;
1844 /* first we must resolve the class containg the method */
1846 if (!resolve_class_from_name(referer, refmethod,
1847 methodref->p.classref->name, resolveLazy, true, true, &container))
1849 /* the class reference could not be resolved */
1850 return resolveFailed; /* exception */
1853 return resolveDeferred; /* be lazy */
1855 assert(container->state & CLASS_LINKED);
1857 /* now we must find the declaration of the method in `container`
1858 * or one of its superclasses */
1860 if (container->flags & ACC_INTERFACE) {
1861 mi = class_resolveinterfacemethod(container,
1863 methodref->descriptor,
1867 mi = class_resolveclassmethod(container,
1869 methodref->descriptor,
1874 /* The method does not exist. But since we were called lazily, */
1875 /* this error must not be reported now. (It will be reported */
1876 /* if eager resolving of this method is ever tried.) */
1878 *exceptionptr = NULL;
1879 return resolveDeferred; /* be lazy */
1882 if (iptr->opc == ICMD_INVOKESPECIAL) {
1883 mi = resolve_method_invokespecial_lookup(refmethod, mi);
1885 return resolveFailed; /* exception */
1888 /* have the method params already been parsed? no, do it. */
1890 if (!mi->parseddesc->params)
1891 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
1892 return resolveFailed;
1894 /* cache the result of the resolution */
1896 methodref->p.method = mi;
1898 resolved_the_method:
1900 #if defined(ENABLE_VERIFIER)
1902 result = resolve_method_verifier_checks(refmethod, methodref,
1905 iptr->opc == ICMD_INVOKESTATIC,
1906 iptr->opc == ICMD_INVOKESPECIAL,
1908 if (result != resolveSucceeded)
1911 #endif /* defined(ENABLE_VERIFIER) */
1913 /* if this call is monomorphic, turn it into an INVOKESPECIAL */
1915 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1916 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1918 iptr->opc = ICMD_INVOKESPECIAL;
1922 return resolveSucceeded;
1925 resolve_result_t resolve_method_lazy(instruction *iptr,stackptr curstack,
1926 methodinfo *refmethod)
1929 classinfo *container;
1931 constant_FMIref *methodref;
1932 resolve_result_t result;
1937 #ifdef RESOLVE_VERBOSE
1938 fprintf(stderr,"resolve_method_lazy\n");
1941 /* the class containing the reference */
1943 referer = refmethod->class;
1946 /* the method reference */
1948 INSTRUCTION_GET_METHODREF(iptr,methodref);
1950 /* check if the method itself is already resolved */
1952 if (IS_FMIREF_RESOLVED(methodref)) {
1953 mi = methodref->p.method;
1954 container = mi->class;
1955 goto resolved_the_method;
1958 /* first we must resolve the class containg the method */
1960 if (!resolve_class_from_name(referer,refmethod,
1961 methodref->p.classref->name,resolveLazy,true,true,&container))
1963 /* the class reference could not be resolved */
1964 return resolveFailed; /* exception */
1967 return resolveDeferred; /* be lazy */
1969 assert(container->state & CLASS_LINKED);
1971 /* now we must find the declaration of the method in `container`
1972 * or one of its superclasses */
1974 if (container->flags & ACC_INTERFACE) {
1975 mi = class_resolveinterfacemethod(container,
1977 methodref->descriptor,
1981 mi = class_resolveclassmethod(container,
1983 methodref->descriptor,
1988 /* The method does not exist. But since we were called lazily, */
1989 /* this error must not be reported now. (It will be reported */
1990 /* if eager resolving of this method is ever tried.) */
1992 *exceptionptr = NULL;
1993 return resolveDeferred; /* be lazy */
1996 if (iptr->opc == ICMD_INVOKESPECIAL) {
1997 mi = resolve_method_invokespecial_lookup(refmethod,mi);
1999 return resolveFailed; /* exception */
2002 /* have the method params already been parsed? no, do it. */
2004 if (!mi->parseddesc->params)
2005 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2006 return resolveFailed;
2008 /* cache the result of the resolution */
2010 methodref->p.method = mi;
2012 resolved_the_method:
2014 #if defined(ENABLE_VERIFIER)
2016 result = resolve_method_verifier_checks(refmethod,methodref,container,
2018 iptr->opc == ICMD_INVOKESTATIC,
2019 iptr->opc == ICMD_INVOKESPECIAL,
2021 if (result != resolveSucceeded)
2024 #endif /* defined(ENABLE_VERIFIER) */
2026 /* if this call is monomorphic, turn it into an INVOKESPECIAL */
2028 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
2029 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
2031 iptr->opc = ICMD_INVOKESPECIAL;
2035 return resolveSucceeded;
2038 /* resolve_method **************************************************************
2040 Resolve an unresolved method reference
2043 ref..............struct containing the reference
2044 mode.............mode of resolution:
2045 resolveLazy...only resolve if it does not
2046 require loading classes
2047 resolveEager..load classes if necessary
2050 *result..........set to the result of resolution, or to NULL if
2051 the reference has not been resolved
2052 In the case of an exception, *result is
2053 guaranteed to be set to NULL.
2056 true.............everything ok
2057 (*result may still be NULL for resolveLazy)
2058 false............an exception has been thrown
2060 *******************************************************************************/
2062 bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2065 classinfo *container;
2066 classinfo *declarer;
2068 typedesc *paramtypes;
2071 resolve_result_t checkresult;
2075 assert(mode == resolveLazy || mode == resolveEager);
2077 #ifdef RESOLVE_VERBOSE
2078 unresolved_method_debug_dump(ref,stderr);
2083 /* the class containing the reference */
2085 referer = ref->referermethod->class;
2088 /* check if the method itself is already resolved */
2090 if (IS_FMIREF_RESOLVED(ref->methodref)) {
2091 mi = ref->methodref->p.method;
2092 container = mi->class;
2093 goto resolved_the_method;
2096 /* first we must resolve the class containing the method */
2098 if (!resolve_class_from_name(referer,ref->referermethod,
2099 ref->methodref->p.classref->name,mode,true,true,&container))
2101 /* the class reference could not be resolved */
2102 return false; /* exception */
2105 return true; /* be lazy */
2108 assert(container->state & CLASS_LINKED);
2110 /* now we must find the declaration of the method in `container`
2111 * or one of its superclasses */
2113 if (container->flags & ACC_INTERFACE) {
2114 mi = class_resolveinterfacemethod(container,
2115 ref->methodref->name,
2116 ref->methodref->descriptor,
2120 mi = class_resolveclassmethod(container,
2121 ref->methodref->name,
2122 ref->methodref->descriptor,
2127 if (mode == resolveLazy) {
2128 /* The method does not exist. But since we were called lazily, */
2129 /* this error must not be reported now. (It will be reported */
2130 /* if eager resolving of this method is ever tried.) */
2132 *exceptionptr = NULL;
2133 return true; /* be lazy */
2136 return false; /* exception */ /* XXX set exceptionptr? */
2139 /* { the method reference has been resolved } */
2141 if (ref->flags & RESOLVE_SPECIAL) {
2142 mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2144 return false; /* exception */
2147 /* have the method params already been parsed? no, do it. */
2149 if (!mi->parseddesc->params)
2150 if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
2153 /* cache the resolution */
2155 ref->methodref->p.method = mi;
2157 resolved_the_method:
2159 #ifdef ENABLE_VERIFIER
2162 checkresult = resolve_method_verifier_checks(ref->referermethod,
2166 (ref->flags & RESOLVE_STATIC),
2167 (ref->flags & RESOLVE_SPECIAL),
2170 if (checkresult != resolveSucceeded)
2171 return (bool) checkresult;
2173 declarer = mi->class;
2175 assert(referer->state & CLASS_LINKED);
2177 /* for non-static methods we have to check the constraints on the */
2180 if (!(ref->flags & RESOLVE_STATIC)) {
2181 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2182 &(ref->instancetypes),
2183 CLASSREF_OR_CLASSINFO(container),
2185 resolveLinkageError);
2186 if (checkresult != resolveSucceeded)
2187 return (bool) checkresult;
2194 /* check subtype constraints for TYPE_ADR parameters */
2196 assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2197 paramtypes = mi->parseddesc->paramtypes;
2199 for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2200 if (paramtypes[i+instancecount].type == TYPE_ADR) {
2201 if (ref->paramconstraints) {
2202 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2203 ref->paramconstraints + i,
2204 CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
2206 resolveLinkageError);
2207 if (checkresult != resolveSucceeded)
2208 return (bool) checkresult;
2213 /* check protected access */
2215 if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2217 checkresult = resolve_and_check_subtype_set(ref->referermethod,
2218 &(ref->instancetypes),
2219 CLASSREF_OR_CLASSINFO(referer),
2221 resolveIllegalAccessError);
2222 if (checkresult != resolveSucceeded)
2223 return (bool) checkresult;
2226 #endif /* ENABLE_VERIFIER */
2233 /* resolve_method_eager ********************************************************
2235 Resolve an unresolved method reference eagerly.
2238 ref..............struct containing the reference
2241 methodinfo * to the method, or
2242 NULL if an exception has been thrown
2244 *******************************************************************************/
2246 methodinfo * resolve_method_eager(unresolved_method *ref)
2250 if (!resolve_method(ref,resolveEager,&mi))
2256 /******************************************************************************/
2257 /* CREATING THE DATA STRUCTURES */
2258 /******************************************************************************/
2260 #ifdef ENABLE_VERIFIER
2261 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2262 methodinfo *refmethod,
2263 unresolved_subtype_set *stset,
2265 constant_classref *declaredtype)
2273 #ifdef RESOLVE_VERBOSE
2274 fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
2275 #ifdef TYPEINFO_DEBUG
2276 typeinfo_print(stderr,tinfo,4);
2278 fprintf(stderr," declared type:");utf_fprint_printable_ascii(stderr,declaredtype->name);
2279 fprintf(stderr,"\n");
2282 if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
2283 exceptions_throw_verifyerror(refmethod,
2284 "Invalid use of returnAddress");
2288 if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
2289 exceptions_throw_verifyerror(refmethod,
2290 "Invalid use of uninitialized object");
2294 /* the nulltype is always assignable */
2295 if (TYPEINFO_IS_NULLTYPE(*tinfo))
2298 /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2299 if (declaredtype->name == utf_java_lang_Object
2300 && referer->classloader == NULL)
2305 if (tinfo->merged) {
2306 count = tinfo->merged->count;
2307 stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2308 for (i=0; i<count; ++i) {
2309 classref_or_classinfo c = tinfo->merged->list[i];
2310 if (tinfo->dimension > 0) {
2311 /* a merge of array types */
2312 /* the merged list contains the possible _element_ types, */
2313 /* so we have to create array types with these elements. */
2314 if (IS_CLASSREF(c)) {
2315 c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2318 c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2321 stset->subtyperefs[i] = c;
2323 stset->subtyperefs[count].any = NULL; /* terminate */
2326 if ((IS_CLASSREF(tinfo->typeclass)
2327 ? tinfo->typeclass.ref->name
2328 : tinfo->typeclass.cls->name) == declaredtype->name)
2330 /* the class names are the same */
2331 /* equality is guaranteed by the loading constraints */
2335 stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2336 stset->subtyperefs[0] = tinfo->typeclass;
2337 stset->subtyperefs[1].any = NULL; /* terminate */
2344 UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2347 #endif /* ENABLE_VERIFIER */
2349 /* create_unresolved_class *****************************************************
2351 Create an unresolved_class struct for the given class reference
2354 refmethod........the method triggering the resolution (if any)
2355 classref.........the class reference
2356 valuetype........value type to check against the resolved class
2357 may be NULL, if no typeinfo is available
2360 a pointer to a new unresolved_class struct, or
2361 NULL if an exception has been thrown
2363 *******************************************************************************/
2365 #ifdef ENABLE_VERIFIER
2366 unresolved_class * create_unresolved_class(methodinfo *refmethod,
2367 constant_classref *classref,
2368 typeinfo *valuetype)
2370 unresolved_class *ref;
2372 #ifdef RESOLVE_VERBOSE
2373 fprintf(stderr,"create_unresolved_class\n");
2374 fprintf(stderr," referer: ");utf_fprint_printable_ascii(stderr,classref->referer->name);fputc('\n',stderr);
2376 fprintf(stderr," rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
2377 fprintf(stderr," rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
2379 fprintf(stderr," name : ");utf_fprint_printable_ascii(stderr,classref->name);fputc('\n',stderr);
2382 ref = NEW(unresolved_class);
2383 ref->classref = classref;
2384 ref->referermethod = refmethod;
2387 if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2388 &(ref->subtypeconstraints),valuetype,classref))
2392 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2397 #endif /* ENABLE_VERIFIER */
2399 /* create_unresolved_field *****************************************************
2401 Create an unresolved_field struct for the given field access instruction
2404 referer..........the class containing the reference
2405 refmethod........the method triggering the resolution (if any)
2406 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2409 a pointer to a new unresolved_field struct, or
2410 NULL if an exception has been thrown
2412 *******************************************************************************/
2414 unresolved_field * new_create_unresolved_field(classinfo *referer,
2415 methodinfo *refmethod,
2416 new_instruction *iptr)
2418 unresolved_field *ref;
2419 constant_FMIref *fieldref = NULL;
2421 #ifdef RESOLVE_VERBOSE
2422 fprintf(stderr,"create_unresolved_field\n");
2423 fprintf(stderr," referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
2424 fprintf(stderr," rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
2425 fprintf(stderr," rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
2428 ref = NEW(unresolved_field);
2430 ref->referermethod = refmethod;
2431 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2433 switch (iptr->opc) {
2435 ref->flags |= RESOLVE_PUTFIELD;
2438 case ICMD_PUTFIELDCONST:
2439 ref->flags |= RESOLVE_PUTFIELD;
2442 case ICMD_PUTSTATIC:
2443 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2446 case ICMD_PUTSTATICCONST:
2447 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2453 case ICMD_GETSTATIC:
2454 ref->flags |= RESOLVE_STATIC;
2457 #if !defined(NDEBUG)
2463 fieldref = iptr->sx.s23.s3.fmiref;
2467 #ifdef RESOLVE_VERBOSE
2468 fprintf(stderr," class : ");utf_fprint_printable_ascii(stderr,fieldref->classref->name);fputc('\n',stderr);
2469 fprintf(stderr," name : ");utf_fprint_printable_ascii(stderr,fieldref->name);fputc('\n',stderr);
2470 fprintf(stderr," desc : ");utf_fprint_printable_ascii(stderr,fieldref->descriptor);fputc('\n',stderr);
2471 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
2473 /*fprintf(stderr," opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2476 ref->fieldref = fieldref;
2481 unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refmethod,
2484 unresolved_field *ref;
2485 constant_FMIref *fieldref = NULL;
2487 #ifdef RESOLVE_VERBOSE
2488 fprintf(stderr,"create_unresolved_field\n");
2489 fprintf(stderr," referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
2490 fprintf(stderr," rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
2491 fprintf(stderr," rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
2494 ref = NEW(unresolved_field);
2496 ref->referermethod = refmethod;
2497 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2499 switch (iptr[0].opc) {
2501 ref->flags |= RESOLVE_PUTFIELD;
2502 fieldref = (constant_FMIref *) iptr[0].val.a;
2505 case ICMD_PUTFIELDCONST:
2506 ref->flags |= RESOLVE_PUTFIELD;
2507 fieldref = (constant_FMIref *) iptr[1].val.a;
2510 case ICMD_PUTSTATIC:
2511 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2512 fieldref = (constant_FMIref *) iptr[0].val.a;
2515 case ICMD_PUTSTATICCONST:
2516 ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2517 fieldref = (constant_FMIref *) iptr[1].val.a;
2521 fieldref = (constant_FMIref *) iptr[0].val.a;
2524 case ICMD_GETSTATIC:
2525 ref->flags |= RESOLVE_STATIC;
2526 fieldref = (constant_FMIref *) iptr[0].val.a;
2532 #ifdef RESOLVE_VERBOSE
2533 fprintf(stderr," class : ");utf_fprint_printable_ascii(stderr,fieldref->classref->name);fputc('\n',stderr);
2534 fprintf(stderr," name : ");utf_fprint_printable_ascii(stderr,fieldref->name);fputc('\n',stderr);
2535 fprintf(stderr," desc : ");utf_fprint_printable_ascii(stderr,fieldref->descriptor);fputc('\n',stderr);
2536 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
2538 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2541 ref->fieldref = fieldref;
2546 /* constrain_unresolved_field **************************************************
2548 Record subtype constraints for a field access.
2551 ref..............the unresolved_field structure of the access
2552 referer..........the class containing the reference
2553 refmethod........the method triggering the resolution (if any)
2554 iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2555 stack............the input stack of the instruction
2558 true.............everything ok
2559 false............an exception has been thrown
2561 *******************************************************************************/
2563 #ifdef ENABLE_VERIFIER
2564 bool constrain_unresolved_field(unresolved_field *ref,
2565 classinfo *referer, methodinfo *refmethod,
2567 stackelement *stack)
2569 constant_FMIref *fieldref;
2570 stackelement *instanceslot = NULL;
2573 typeinfo *tip = NULL;
2578 fieldref = ref->fieldref;
2581 #ifdef RESOLVE_VERBOSE
2582 fprintf(stderr,"constrain_unresolved_field\n");
2583 fprintf(stderr," referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
2584 fprintf(stderr," rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
2585 fprintf(stderr," rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
2586 fprintf(stderr," class : ");utf_fprint_printable_ascii(stderr,fieldref->classref->name);fputc('\n',stderr);
2587 fprintf(stderr," name : ");utf_fprint_printable_ascii(stderr,fieldref->name);fputc('\n',stderr);
2588 fprintf(stderr," desc : ");utf_fprint_printable_ascii(stderr,fieldref->descriptor);fputc('\n',stderr);
2589 fprintf(stderr," type : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
2591 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2594 switch (iptr[0].opc) {
2596 instanceslot = stack->prev;
2597 tip = &(stack->typeinfo);
2600 case ICMD_PUTFIELDCONST:
2601 instanceslot = stack;
2604 case ICMD_PUTSTATIC:
2605 tip = &(stack->typeinfo);
2609 instanceslot = stack;
2613 assert(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
2614 fd = fieldref->parseddesc.fd;
2617 /* record subtype constraints for the instance type, if any */
2621 /* The instanceslot must contain a reference to a non-array type */
2622 if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
2623 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
2626 if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
2627 exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
2631 if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
2632 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2634 /* The instruction writes a field in an uninitialized object. */
2635 /* This is only allowed when a field of an uninitialized 'this' object is */
2636 /* written inside an initialization method */
2638 classinfo *initclass;
2639 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2642 exceptions_throw_verifyerror(refmethod,"accessing field of uninitialized object");
2645 /* XXX check that class of field == refmethod->class */
2646 initclass = refmethod->class; /* XXX classrefs */
2647 assert(initclass->state & CLASS_LOADED);
2648 assert(initclass->state & CLASS_LINKED);
2650 typeinfo_init_classinfo(&tinfo,initclass);
2654 insttip = &(instanceslot->typeinfo);
2656 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2657 &(ref->instancetypes),insttip,fieldref->p.classref))
2661 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2664 /* record subtype constraints for the value type, if any */
2666 if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2668 /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
2670 if (INSTRUCTION_PUTCONST_VALUE_ADR(iptr)) {
2671 assert(class_java_lang_String);
2672 assert(class_java_lang_String->state & CLASS_LOADED);
2673 assert(class_java_lang_String->state & CLASS_LINKED);
2674 typeinfo_init_classinfo(&tinfo,class_java_lang_String);
2677 TYPEINFO_INIT_NULLTYPE(tinfo);
2679 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2680 &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref))
2684 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2689 #endif /* ENABLE_VERIFIER */
2691 /* create_unresolved_method ****************************************************
2693 Create an unresolved_method struct for the given method invocation
2696 referer..........the class containing the reference
2697 refmethod........the method triggering the resolution (if any)
2698 iptr.............the INVOKE* instruction
2701 a pointer to a new unresolved_method struct, or
2702 NULL if an exception has been thrown
2704 *******************************************************************************/
2706 unresolved_method * new_create_unresolved_method(classinfo *referer,
2707 methodinfo *refmethod,
2708 new_instruction *iptr)
2710 unresolved_method *ref;
2711 constant_FMIref *methodref;
2714 methodref = iptr->sx.s23.s3.fmiref;
2716 staticmethod = (iptr->opc == ICMD_INVOKESTATIC);
2718 #ifdef RESOLVE_VERBOSE
2719 fprintf(stderr,"create_unresolved_method\n");
2720 fprintf(stderr," referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
2721 fprintf(stderr," rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
2722 fprintf(stderr," rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
2723 fprintf(stderr," class : ");utf_fprint_printable_ascii(stderr,methodref->classref->name);fputc('\n',stderr);
2724 fprintf(stderr," name : ");utf_fprint_printable_ascii(stderr,methodref->name);fputc('\n',stderr);
2725 fprintf(stderr," desc : ");utf_fprint_printable_ascii(stderr,methodref->descriptor);fputc('\n',stderr);
2726 /*fprintf(stderr," opcode : %d %s\n",iptr->opc,icmd_names[iptr->opc]);*/
2729 /* allocate params if necessary */
2730 if (!methodref->parseddesc.md->params)
2731 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2732 (staticmethod) ? ACC_STATIC : ACC_NONE))
2735 /* create the data structure */
2736 ref = NEW(unresolved_method);
2737 ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
2738 | ((iptr->opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
2739 ref->referermethod = refmethod;
2740 ref->methodref = methodref;
2741 ref->paramconstraints = NULL;
2742 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2747 unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *refmethod,
2750 unresolved_method *ref;
2751 constant_FMIref *methodref;
2754 methodref = (constant_FMIref *) iptr[0].val.a;
2756 staticmethod = (iptr[0].opc == ICMD_INVOKESTATIC);
2758 #ifdef RESOLVE_VERBOSE
2759 fprintf(stderr,"create_unresolved_method\n");
2760 fprintf(stderr," referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
2761 fprintf(stderr," rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
2762 fprintf(stderr," rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
2763 fprintf(stderr," class : ");utf_fprint_printable_ascii(stderr,methodref->classref->name);fputc('\n',stderr);
2764 fprintf(stderr," name : ");utf_fprint_printable_ascii(stderr,methodref->name);fputc('\n',stderr);
2765 fprintf(stderr," desc : ");utf_fprint_printable_ascii(stderr,methodref->descriptor);fputc('\n',stderr);
2766 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2769 /* allocate params if necessary */
2770 if (!methodref->parseddesc.md->params)
2771 if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
2772 (staticmethod) ? ACC_STATIC : ACC_NONE))
2775 /* create the data structure */
2776 ref = NEW(unresolved_method);
2777 ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
2778 | ((iptr[0].opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
2779 ref->referermethod = refmethod;
2780 ref->methodref = methodref;
2781 ref->paramconstraints = NULL;
2782 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2787 /* constrain_unresolved_method *************************************************
2789 Record subtype constraints for the arguments of a method call.
2792 ref..............the unresolved_method structure of the call
2793 referer..........the class containing the reference
2794 refmethod........the method triggering the resolution (if any)
2795 iptr.............the INVOKE* instruction
2796 stack............the input stack of the instruction
2799 true.............everything ok
2800 false............an exception has been thrown
2802 *******************************************************************************/
2804 #ifdef ENABLE_VERIFIER
2805 bool constrain_unresolved_method(unresolved_method *ref,
2806 classinfo *referer, methodinfo *refmethod,
2808 stackelement *stack)
2810 constant_FMIref *methodref;
2811 constant_classref *instanceref;
2812 stackelement *instanceslot = NULL;
2813 stackelement *param;
2821 methodref = ref->methodref;
2823 md = methodref->parseddesc.md;
2825 assert(md->params != NULL);
2827 /* XXX clean this up */
2828 instanceref = IS_FMIREF_RESOLVED(methodref)
2829 ? class_get_self_classref(methodref->p.method->class)
2830 : methodref->p.classref;
2832 #ifdef RESOLVE_VERBOSE
2833 fprintf(stderr,"constrain_unresolved_method\n");
2834 fprintf(stderr," referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
2835 fprintf(stderr," rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
2836 fprintf(stderr," rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
2837 fprintf(stderr," class : ");utf_fprint_printable_ascii(stderr,methodref->classref->name);fputc('\n',stderr);
2838 fprintf(stderr," name : ");utf_fprint_printable_ascii(stderr,methodref->name);fputc('\n',stderr);
2839 fprintf(stderr," desc : ");utf_fprint_printable_ascii(stderr,methodref->descriptor);fputc('\n',stderr);
2840 /*fprintf(stderr," opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
2843 if ((ref->flags & RESOLVE_STATIC) == 0) {
2844 /* find the instance slot under all the parameter slots on the stack */
2845 instanceslot = stack;
2846 for (i=1; i<md->paramcount; ++i)
2847 instanceslot = instanceslot->prev;
2854 assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
2856 /* record subtype constraints for the instance type, if any */
2860 assert(instanceslot->type == TYPE_ADR);
2862 if (iptr[0].opc == ICMD_INVOKESPECIAL &&
2863 TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
2864 { /* XXX clean up */
2865 instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
2866 classref_or_classinfo initclass = (ins) ? ICMD_ACONST_CLASSREF_OR_CLASSINFO(ins-1)
2867 : CLASSREF_OR_CLASSINFO(refmethod->class);
2869 if (!typeinfo_init_class(tip,initclass))
2873 tip = &(instanceslot->typeinfo);
2875 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2876 &(ref->instancetypes),tip,instanceref))
2880 /* record subtype constraints for the parameter types, if any */
2882 for (i=md->paramcount-1-instancecount; i>=0; --i, param=param->prev) {
2883 type = md->paramtypes[i+instancecount].type;
2886 assert(type == param->type);
2888 if (type == TYPE_ADR) {
2889 if (!ref->paramconstraints) {
2890 ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2891 for (j=md->paramcount-1-instancecount; j>i; --j)
2892 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2894 assert(ref->paramconstraints);
2895 if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
2896 ref->paramconstraints + i,&(param->typeinfo),
2897 md->paramtypes[i+instancecount].classref))
2901 if (ref->paramconstraints)
2902 UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2908 #endif /* ENABLE_VERIFIER */
2910 /******************************************************************************/
2911 /* FREEING MEMORY */
2912 /******************************************************************************/
2914 #ifdef ENABLE_VERIFIER
2915 inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2918 classref_or_classinfo *p = list;
2920 /* this is silly. we *only* need to count the elements for MFREE */
2923 MFREE(list,classref_or_classinfo,(p - list));
2926 #endif /* ENABLE_VERIFIER */
2928 /* unresolved_class_free *******************************************************
2930 Free the memory used by an unresolved_class
2933 ref..............the unresolved_class
2935 *******************************************************************************/
2937 void unresolved_class_free(unresolved_class *ref)
2941 #ifdef ENABLE_VERIFIER
2942 unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2944 FREE(ref,unresolved_class);
2947 /* unresolved_field_free *******************************************************
2949 Free the memory used by an unresolved_field
2952 ref..............the unresolved_field
2954 *******************************************************************************/
2956 void unresolved_field_free(unresolved_field *ref)
2960 #ifdef ENABLE_VERIFIER
2961 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2962 unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2964 FREE(ref,unresolved_field);
2967 /* unresolved_method_free ******************************************************
2969 Free the memory used by an unresolved_method
2972 ref..............the unresolved_method
2974 *******************************************************************************/
2976 void unresolved_method_free(unresolved_method *ref)
2980 #ifdef ENABLE_VERIFIER
2981 unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2982 if (ref->paramconstraints) {
2984 int count = ref->methodref->parseddesc.md->paramcount;
2986 for (i=0; i<count; ++i)
2987 unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2988 MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2991 FREE(ref,unresolved_method);
2994 /******************************************************************************/
2996 /******************************************************************************/
2998 #if !defined(NDEBUG)
3000 /* unresolved_subtype_set_debug_dump *******************************************
3002 Print debug info for unresolved_subtype_set to stream
3005 stset............the unresolved_subtype_set
3006 file.............the stream
3008 *******************************************************************************/
3010 void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
3012 classref_or_classinfo *p;
3014 if (SUBTYPESET_IS_EMPTY(*stset)) {
3015 fprintf(file," (empty)\n");
3018 p = stset->subtyperefs;
3019 for (;p->any; ++p) {
3020 if (IS_CLASSREF(*p)) {
3021 fprintf(file," ref: ");
3022 utf_fprint_printable_ascii(file,p->ref->name);
3025 fprintf(file," cls: ");
3026 utf_fprint_printable_ascii(file,p->cls->name);
3033 /* unresolved_class_debug_dump *************************************************
3035 Print debug info for unresolved_class to stream
3038 ref..............the unresolved_class
3039 file.............the stream
3041 *******************************************************************************/
3043 void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
3045 fprintf(file,"unresolved_class(%p):\n",(void *)ref);
3047 fprintf(file," referer : ");
3048 utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
3049 fprintf(file," refmethod : ");
3050 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3051 fprintf(file," refmethodd: ");
3052 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3053 fprintf(file," classname : ");
3054 utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
3055 fprintf(file," subtypeconstraints:\n");
3056 unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
3060 /* unresolved_field_debug_dump *************************************************
3062 Print debug info for unresolved_field to stream
3065 ref..............the unresolved_field
3066 file.............the stream
3068 *******************************************************************************/
3070 void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3072 fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3074 fprintf(file," referer : ");
3075 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3076 fprintf(file," refmethod : ");
3077 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3078 fprintf(file," refmethodd: ");
3079 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3080 fprintf(file," classname : ");
3081 utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3082 fprintf(file," name : ");
3083 utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3084 fprintf(file," descriptor: ");
3085 utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3086 fprintf(file," parseddesc: ");
3087 descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3088 fprintf(file," flags : %04x\n",ref->flags);
3089 fprintf(file," instancetypes:\n");
3090 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3091 fprintf(file," valueconstraints:\n");
3092 unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3096 /* unresolved_method_debug_dump ************************************************
3098 Print debug info for unresolved_method to stream
3101 ref..............the unresolved_method
3102 file.............the stream
3104 *******************************************************************************/
3106 void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3110 fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3112 fprintf(file," referer : ");
3113 utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
3114 fprintf(file," refmethod : ");
3115 utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3116 fprintf(file," refmethodd: ");
3117 utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3118 fprintf(file," classname : ");
3119 utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3120 fprintf(file," name : ");
3121 utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3122 fprintf(file," descriptor: ");
3123 utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3124 fprintf(file," parseddesc: ");
3125 descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3126 fprintf(file," flags : %04x\n",ref->flags);
3127 fprintf(file," instancetypes:\n");
3128 unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3129 fprintf(file," paramconstraints:\n");
3130 if (ref->paramconstraints) {
3131 for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3132 fprintf(file," param %d:\n",i);
3133 unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3137 fprintf(file," (empty)\n");
3141 #endif /* !defined(NDEBUG) */
3144 * These are local overrides for various environment variables in Emacs.
3145 * Please do not remove this and leave it at the end of the file, where
3146 * Emacs will automagically detect them.
3147 * ---------------------------------------------------------------------
3150 * indent-tabs-mode: t
3154 * vim:noexpandtab:sw=4:ts=4: