1 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: typeinfo.c 8343 2007-08-17 21:39:32Z michi $
35 #include "mm/memory.h"
37 #include "toolbox/logging.h"
40 #include "vm/exceptions.h"
41 #include "vm/primitive.h"
42 #include "vm/resolve.h"
44 #include "vm/jit/jit.h"
45 #include "vm/jit/verify/typeinfo.h"
47 #include "vmcore/class.h"
48 #include "vmcore/descriptor.h"
49 #include "vmcore/loader.h"
52 /* check if a linked class is an array class. Only use for linked classes! */
53 #define CLASSINFO_IS_ARRAY(clsinfo) ((clsinfo)->vftbl->arraydesc != NULL)
55 /* check if a linked class implements the interface with the given index */
56 #define CLASSINFO_IMPLEMENTS_INTERFACE(cls,index) \
57 ( ((index) < (cls)->vftbl->interfacetablelength) \
58 && ( (cls)->vftbl->interfacetable[-(index)] != NULL ) )
60 /******************************************************************************/
62 /******************************************************************************/
65 #define TYPEINFO_ASSERT(cond) assert(cond)
67 #define TYPEINFO_ASSERT(cond)
70 /**********************************************************************/
71 /* TYPEVECTOR FUNCTIONS */
72 /**********************************************************************/
74 #if defined(ENABLE_VERIFIER)
76 /* typevector_copy *************************************************************
78 Return a copy of the given typevector.
81 src..............typevector set to copy, must be != NULL
82 size.............number of elements per typevector
85 a pointer to the new typevector set
87 *******************************************************************************/
90 typevector_copy(varinfo *src, int size)
96 dst = DNEW_TYPEVECTOR(size);
97 memcpy(dst,src,TYPEVECTOR_SIZE(size));
102 /* typevector_copy_inplace *****************************************************
104 Copy a typevector to a given destination.
107 src..............typevector to copy, must be != NULL
108 dst..............destination to write the copy to
109 size.............number of elements per typevector
111 *******************************************************************************/
114 typevector_copy_inplace(varinfo *src,varinfo *dst,int size)
116 memcpy(dst,src,TYPEVECTOR_SIZE(size));
119 /* typevector_checktype ********************************************************
121 Check if the typevector contains a given type at a given index.
124 vec..............typevector set, must be != NULL
125 index............index of component to check
126 type.............TYPE_* constant to check against
129 true if the typevector contains TYPE at INDEX,
132 *******************************************************************************/
135 typevector_checktype(varinfo *vec,int index,int type)
137 TYPEINFO_ASSERT(vec);
139 return vec[index].type == type;
142 /* typevector_checkreference ***************************************************
144 Check if the typevector contains a reference at a given index.
147 vec..............typevector, must be != NULL
148 index............index of component to check
151 true if the typevector contains a reference at INDEX,
154 *******************************************************************************/
157 typevector_checkreference(varinfo *vec, int index)
159 TYPEINFO_ASSERT(vec);
160 return TYPEDESC_IS_REFERENCE(vec[index]);
163 /* typevectorset_checkretaddr **************************************************
165 Check if the typevectors contains a returnAddress at a given index.
168 vec..............typevector, must be != NULL
169 index............index of component to check
172 true if the typevector contains a returnAddress at INDEX,
175 *******************************************************************************/
178 typevector_checkretaddr(varinfo *vec,int index)
180 TYPEINFO_ASSERT(vec);
181 return TYPEDESC_IS_RETURNADDRESS(vec[index]);
184 /* typevector_store ************************************************************
186 Store a type at a given index in the typevector.
189 vec..............typevector set, must be != NULL
190 index............index of component to set
191 type.............TYPE_* constant of type to set
192 info.............typeinfo of type to set, may be NULL,
195 *******************************************************************************/
198 typevector_store(varinfo *vec,int index,int type,typeinfo *info)
200 TYPEINFO_ASSERT(vec);
202 vec[index].type = type;
204 TYPEINFO_COPY(*info,vec[index].typeinfo);
207 /* typevector_store_retaddr ****************************************************
209 Store a returnAddress type at a given index in the typevector.
212 vec..............typevector set, must be != NULL
213 index............index of component to set
214 info.............typeinfo of the returnAddress.
216 *******************************************************************************/
219 typevector_store_retaddr(varinfo *vec,int index,typeinfo *info)
221 TYPEINFO_ASSERT(vec);
222 TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
224 vec[index].type = TYPE_ADR;
225 TYPEINFO_INIT_RETURNADDRESS(vec[index].typeinfo,
226 TYPEINFO_RETURNADDRESS(*info));
229 /* typevector_init_object ******************************************************
231 Replace all uninitialized object types in the typevector set which were
232 created by the given instruction by initialized object types.
235 set..............typevector set
236 ins..............instruction which created the uninitialized object type
237 initclass........class of the initialized object type to set
238 size.............number of elements per typevector
241 true.............success
242 false............an exception has been thrown
244 XXX maybe we should do the lazy resolving before calling this function
246 *******************************************************************************/
249 typevector_init_object(varinfo *set,void *ins,
250 classref_or_classinfo initclass,
255 for (i=0; i<size; ++i) {
256 if (set[i].type == TYPE_ADR
257 && TYPEINFO_IS_NEWOBJECT(set[i].typeinfo)
258 && TYPEINFO_NEWOBJECT_INSTRUCTION(set[i].typeinfo) == ins)
260 if (!typeinfo_init_class(&(set[i].typeinfo),initclass))
267 /* typevector_merge ************************************************************
269 Merge a typevector with another one.
270 The given typevectors must have the same number of components.
273 m................method for exception messages
274 dst..............the first typevector
275 y................the second typevector
276 size.............number of elements per typevector
279 *dst.............the resulting typevector
282 typecheck_TRUE...dst has been modified
283 typecheck_FALSE..dst has not been modified
284 typecheck_FAIL...an exception has been thrown
286 *******************************************************************************/
289 typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size)
291 bool changed = false;
297 if (a->type != TYPE_VOID && a->type != b->type) {
301 else if (a->type == TYPE_ADR) {
302 if (TYPEINFO_IS_PRIMITIVE(a->typeinfo)) {
303 /* 'a' is a returnAddress */
304 if (!TYPEINFO_IS_PRIMITIVE(b->typeinfo)
305 || (TYPEINFO_RETURNADDRESS(a->typeinfo)
306 != TYPEINFO_RETURNADDRESS(b->typeinfo)))
313 /* 'a' is a reference */
314 if (TYPEINFO_IS_PRIMITIVE(b->typeinfo)) {
319 /* two reference types are merged. There cannot be */
320 /* a merge error. In the worst case we get j.l.O. */
321 r = typeinfo_merge(m,&(a->typeinfo),&(b->typeinfo));
322 if (r == typecheck_FAIL)
334 /**********************************************************************/
335 /* READ-ONLY FUNCTIONS */
336 /* The following functions don't change typeinfo data. */
337 /**********************************************************************/
339 /* typeinfo_is_array ***********************************************************
341 Check whether a typeinfo describes an array type.
344 info.............the typeinfo, must be != NULL
347 true if INFO describes an array type.
349 *******************************************************************************/
352 typeinfo_is_array(typeinfo *info)
354 TYPEINFO_ASSERT(info);
355 return TYPEINFO_IS_ARRAY(*info);
358 /* typeinfo_is_primitive_array *************************************************
360 Check whether a typeinfo describes a primitive array type.
363 info.............the typeinfo, must be != NULL
366 true if INFO describes an array of a primitive type.
368 *******************************************************************************/
371 typeinfo_is_primitive_array(typeinfo *info,int arraytype)
373 TYPEINFO_ASSERT(info);
374 return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
377 /* typeinfo_is_array_of_refs ***************************************************
379 Check whether a typeinfo describes an array of references type.
382 info.............the typeinfo, must be != NULL
385 true if INFO describes an array of a refrence type.
387 *******************************************************************************/
390 typeinfo_is_array_of_refs(typeinfo *info)
392 TYPEINFO_ASSERT(info);
393 return TYPEINFO_IS_ARRAY_OF_REFS(*info);
396 /* interface_extends_interface *************************************************
398 Check if a resolved interface extends a given resolved interface.
401 cls..............the interface, must be linked
402 interf...........the interface to check against
405 true.............CLS extends INTERF
406 false............CLS does not extend INTERF
408 *******************************************************************************/
411 interface_extends_interface(classinfo *cls,classinfo *interf)
415 TYPEINFO_ASSERT(cls);
416 TYPEINFO_ASSERT(interf);
417 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
418 TYPEINFO_ASSERT((cls->flags & ACC_INTERFACE) != 0);
419 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
421 /* first check direct superinterfaces */
422 for (i=0; i<cls->interfacescount; ++i) {
423 if (cls->interfaces[i].cls == interf)
427 /* check indirect superinterfaces */
428 for (i=0; i<cls->interfacescount; ++i) {
429 if (interface_extends_interface(cls->interfaces[i].cls,interf))
436 /* classinfo_implements_interface **********************************************
438 Check if a resolved class implements a given resolved interface.
441 cls..............the class
442 interf...........the interface
445 typecheck_TRUE...CLS implements INTERF
446 typecheck_FALSE..CLS does not implement INTERF
447 typecheck_FAIL...an exception has been thrown
449 *******************************************************************************/
451 static typecheck_result
452 classinfo_implements_interface(classinfo *cls,classinfo *interf)
454 TYPEINFO_ASSERT(cls);
455 TYPEINFO_ASSERT(interf);
456 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
458 if (!(cls->state & CLASS_LINKED))
459 if (!link_class(cls))
460 return typecheck_FAIL;
462 if (cls->flags & ACC_INTERFACE) {
463 /* cls is an interface */
465 return typecheck_TRUE;
467 /* check superinterfaces */
468 return interface_extends_interface(cls,interf);
471 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
472 return CLASSINFO_IMPLEMENTS_INTERFACE(cls,interf->index);
475 /* mergedlist_implements_interface *********************************************
477 Check if all the classes in a given merged list implement a given resolved
481 merged...........the list of merged class types
482 interf...........the interface to check against
485 typecheck_TRUE...all classes implement INTERF
486 typecheck_FALSE..there is at least one class that does not implement
488 typecheck_MAYBE..check cannot be performed now because of unresolved
490 typecheck_FAIL...an exception has been thrown
492 *******************************************************************************/
494 static typecheck_result
495 mergedlist_implements_interface(typeinfo_mergedlist *merged,
499 classref_or_classinfo *mlist;
502 TYPEINFO_ASSERT(interf);
503 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
505 /* Check if there is an non-empty mergedlist. */
507 return typecheck_FALSE;
509 /* If all classinfos in the (non-empty) merged array implement the
510 * interface return true, otherwise false.
512 mlist = merged->list;
515 if (IS_CLASSREF(*mlist)) {
516 return typecheck_MAYBE;
518 r = classinfo_implements_interface((mlist++)->cls,interf);
519 if (r != typecheck_TRUE)
522 return typecheck_TRUE;
525 /* merged_implements_interface *************************************************
527 Check if a possible merged type implements a given resolved interface
531 typeclass........(common) class of the (merged) type
532 merged...........the list of merged class types
533 interf...........the interface to check against
536 typecheck_TRUE...the type implement INTERF
537 typecheck_FALSE..the type does not implement INTERF
538 typecheck_MAYBE..check cannot be performed now because of unresolved
540 typecheck_FAIL...an exception has been thrown
542 *******************************************************************************/
544 static typecheck_result
545 merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
550 /* primitive types don't support interfaces. */
552 return typecheck_FALSE;
554 /* the null type can be cast to any interface type. */
555 if (typeclass == pseudo_class_Null)
556 return typecheck_TRUE;
558 /* check if typeclass implements the interface. */
559 r = classinfo_implements_interface(typeclass,interf);
560 if (r != typecheck_FALSE)
563 /* check the mergedlist */
565 return typecheck_FALSE;
566 return mergedlist_implements_interface(merged,interf);
569 /* merged_is_subclass **********************************************************
571 Check if a possible merged type is a subclass of a given class.
572 A merged type is a subclass of a class C if all types in the merged list
573 are subclasses of C. A sufficient condition for this is that the
574 common type of the merged type is a subclass of C.
577 typeclass........(common) class of the (merged) type
578 MUST be a loaded and linked class
579 merged...........the list of merged class types
580 cls..............the class to theck against
583 typecheck_TRUE...the type is a subclass of CLS
584 typecheck_FALSE..the type is not a subclass of CLS
585 typecheck_MAYBE..check cannot be performed now because of unresolved
587 typecheck_FAIL...an exception has been thrown
589 *******************************************************************************/
591 static typecheck_result
592 merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
596 classref_or_classinfo *mlist;
598 TYPEINFO_ASSERT(cls);
600 /* primitive types aren't subclasses of anything. */
602 return typecheck_FALSE;
604 /* the null type can be cast to any reference type. */
605 if (typeclass == pseudo_class_Null)
606 return typecheck_TRUE;
608 TYPEINFO_ASSERT(typeclass->state & CLASS_LOADED);
609 TYPEINFO_ASSERT(typeclass->state & CLASS_LINKED);
611 /* check if the common typeclass is a subclass of CLS. */
612 if (class_issubclass(typeclass,cls))
613 return typecheck_TRUE;
615 /* check the mergedlist */
617 return typecheck_FALSE;
618 /* If all classinfos in the (non-empty) merged list are subclasses
619 * of CLS, return true, otherwise false.
620 * If there is at least one unresolved type in the list,
621 * return typecheck_MAYBE.
623 mlist = merged->list;
626 if (IS_CLASSREF(*mlist)) {
627 return typecheck_MAYBE;
629 if (!(mlist->cls->state & CLASS_LINKED))
630 if (!link_class(mlist->cls))
631 return typecheck_FAIL;
632 if (!class_issubclass(mlist->cls,cls))
633 return typecheck_FALSE;
636 return typecheck_TRUE;
639 /* typeinfo_is_assignable_to_class *********************************************
641 Check if a type is assignable to a given class type.
644 value............the type of the value
645 dest.............the type of the destination
648 typecheck_TRUE...the type is assignable
649 typecheck_FALSE..the type is not assignable
650 typecheck_MAYBE..check cannot be performed now because of unresolved
652 typecheck_FAIL...an exception has been thrown
654 *******************************************************************************/
657 typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
659 classref_or_classinfo c;
663 TYPEINFO_ASSERT(value);
665 c = value->typeclass;
667 /* assignments of primitive values are not checked here. */
668 if (!c.any && !dest.any)
669 return typecheck_TRUE;
671 /* primitive and reference types are not assignment compatible. */
672 if (!c.any || !dest.any)
673 return typecheck_FALSE;
675 /* the null type can be assigned to any type */
676 if (TYPEINFO_IS_NULLTYPE(*value))
677 return typecheck_TRUE;
679 /* uninitialized objects are not assignable */
680 if (TYPEINFO_IS_NEWOBJECT(*value))
681 return typecheck_FALSE;
683 if (IS_CLASSREF(c)) {
684 /* The value type is an unresolved class reference. */
685 classname = c.ref->name;
688 classname = c.cls->name;
691 if (IS_CLASSREF(dest)) {
692 /* the destination type is an unresolved class reference */
693 /* In this case we cannot tell a lot about assignability. */
695 /* the common case of value and dest type having the same classname */
696 if (dest.ref->name == classname && !value->merged)
697 return typecheck_TRUE;
699 /* we cannot tell if value is assignable to dest, so we */
700 /* leave it up to the resolving code to check this */
701 return typecheck_MAYBE;
704 /* { we know that dest is a loaded class } */
706 if (IS_CLASSREF(c)) {
707 /* the value type is an unresolved class reference */
709 /* the common case of value and dest type having the same classname */
710 if (dest.cls->name == classname)
711 return typecheck_TRUE;
713 /* we cannot tell if value is assignable to dest, so we */
714 /* leave it up to the resolving code to check this */
715 return typecheck_MAYBE;
718 /* { we know that both c and dest are loaded classes } */
719 /* (c may still have a merged list containing unresolved classrefs!) */
721 TYPEINFO_ASSERT(!IS_CLASSREF(c));
722 TYPEINFO_ASSERT(!IS_CLASSREF(dest));
726 TYPEINFO_ASSERT(cls->state & CLASS_LOADED);
727 TYPEINFO_ASSERT(dest.cls->state & CLASS_LOADED);
729 /* maybe we need to link the classes */
730 if (!(cls->state & CLASS_LINKED))
731 if (!link_class(cls))
732 return typecheck_FAIL;
733 if (!(dest.cls->state & CLASS_LINKED))
734 if (!link_class(dest.cls))
735 return typecheck_FAIL;
737 /* { we know that both c and dest are linked classes } */
738 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
739 TYPEINFO_ASSERT(dest.cls->state & CLASS_LINKED);
741 if (dest.cls->flags & ACC_INTERFACE) {
742 /* We are assigning to an interface type. */
743 return merged_implements_interface(cls,value->merged,dest.cls);
746 if (CLASSINFO_IS_ARRAY(dest.cls)) {
747 arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
748 int dimension = arraydesc->dimension;
749 classinfo *elementclass = (arraydesc->elementvftbl)
750 ? arraydesc->elementvftbl->class : NULL;
752 /* We are assigning to an array type. */
753 if (!TYPEINFO_IS_ARRAY(*value))
754 return typecheck_FALSE;
756 /* {Both value and dest.cls are array types.} */
758 /* value must have at least the dimension of dest.cls. */
759 if (value->dimension < dimension)
760 return typecheck_FALSE;
762 if (value->dimension > dimension) {
763 /* value has higher dimension so we need to check
764 * if its component array can be assigned to the
765 * element type of dest.cls */
767 if (!elementclass) return typecheck_FALSE;
769 if (elementclass->flags & ACC_INTERFACE) {
770 /* We are assigning to an interface type. */
771 return classinfo_implements_interface(pseudo_class_Arraystub,
775 /* We are assigning to a class type. */
776 return class_issubclass(pseudo_class_Arraystub,elementclass);
779 /* {value and dest.cls have the same dimension} */
781 if (value->elementtype != arraydesc->elementtype)
782 return typecheck_FALSE;
784 if (value->elementclass.any) {
785 /* We are assigning an array of objects so we have to
786 * check if the elements are assignable.
789 if (elementclass->flags & ACC_INTERFACE) {
790 /* We are assigning to an interface type. */
792 return merged_implements_interface(value->elementclass.cls,
797 /* We are assigning to a class type. */
798 return merged_is_subclass(value->elementclass.cls,value->merged,elementclass);
801 return typecheck_TRUE;
804 /* {dest.cls is not an array} */
805 /* {dest.cls is a loaded class} */
807 /* If there are any unresolved references in the merged list, we cannot */
808 /* tell if the assignment will be ok. */
809 /* This can only happen when cls is java.lang.Object */
810 if (cls == class_java_lang_Object && value->merged) {
811 classref_or_classinfo *mlist = value->merged->list;
812 int i = value->merged->count;
814 if (IS_CLASSREF(*mlist++))
815 return typecheck_MAYBE;
818 /* We are assigning to a class type */
819 if (cls->flags & ACC_INTERFACE)
820 cls = class_java_lang_Object;
822 return merged_is_subclass(cls,value->merged,dest.cls);
825 /* typeinfo_is_assignable ******************************************************
827 Check if a type is assignable to a given type.
830 value............the type of the value
831 dest.............the type of the destination, must not be a merged type
834 typecheck_TRUE...the type is assignable
835 typecheck_FALSE..the type is not assignable
836 typecheck_MAYBE..check cannot be performed now because of unresolved
838 typecheck_FAIL...an exception has been thrown
840 *******************************************************************************/
843 typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
845 TYPEINFO_ASSERT(value);
846 TYPEINFO_ASSERT(dest);
847 TYPEINFO_ASSERT(dest->merged == NULL);
849 return typeinfo_is_assignable_to_class(value,dest->typeclass);
852 /**********************************************************************/
853 /* INITIALIZATION FUNCTIONS */
854 /* The following functions fill in uninitialized typeinfo structures. */
855 /**********************************************************************/
857 /* typeinfo_init_classinfo *****************************************************
859 Initialize a typeinfo to a resolved class.
862 c................the class
865 *info............is initialized
868 true.............success
869 false............an exception has been thrown
871 *******************************************************************************/
874 typeinfo_init_classinfo(typeinfo *info, classinfo *c)
876 if ((info->typeclass.cls = c)->vftbl->arraydesc) {
877 if (c->vftbl->arraydesc->elementvftbl)
878 info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->class;
880 info->elementclass.any = NULL;
881 info->dimension = c->vftbl->arraydesc->dimension;
882 info->elementtype = c->vftbl->arraydesc->elementtype;
885 info->elementclass.any = NULL;
887 info->elementtype = 0;
892 /* typeinfo_init_class *********************************************************
894 Initialize a typeinfo to a possibly unresolved class type.
897 c................the class type
900 *info............is initialized
903 true.............success
904 false............an exception has been thrown
906 *******************************************************************************/
909 typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
915 TYPEINFO_ASSERT(c.any);
916 TYPEINFO_ASSERT(info);
918 /* if necessary, try to resolve lazily */
919 if (!resolve_classref_or_classinfo(NULL /* XXX should know method */,
920 c,resolveLazy,false,true,&cls))
926 typeinfo_init_classinfo(info,cls);
930 /* {the type could no be resolved lazily} */
932 info->typeclass.ref = c.ref;
933 info->elementclass.any = NULL;
937 /* handle array type references */
938 utf_ptr = c.ref->name->text;
939 len = c.ref->name->blength;
940 if (*utf_ptr == '[') {
941 /* count dimensions */
942 while (*utf_ptr == '[') {
947 if (*utf_ptr == 'L') {
950 info->elementtype = ARRAYTYPE_OBJECT;
951 info->elementclass.ref = class_get_classref(c.ref->referer,utf_new(utf_ptr,len));
954 /* an array with primitive element type */
955 /* should have been resolved above */
956 TYPEINFO_ASSERT(false);
962 /* typeinfo_init_from_typedesc *************************************************
964 Initialize a typeinfo from a typedesc.
967 desc.............the typedesc
970 *type............set to the TYPE_* constant of DESC (if type != NULL)
971 *info............receives the typeinfo (if info != NULL)
974 true.............success
975 false............an exception has been thrown
977 *******************************************************************************/
980 typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
982 TYPEINFO_ASSERT(desc);
984 #ifdef TYPEINFO_VERBOSE
985 fprintf(stderr,"typeinfo_init_from_typedesc(");
986 descriptor_debug_print_typedesc(stderr,desc);
987 fprintf(stderr,")\n");
994 if (desc->type == TYPE_ADR) {
995 TYPEINFO_ASSERT(desc->classref);
996 if (!typeinfo_init_class(info,CLASSREF_OR_CLASSINFO(desc->classref)))
1000 TYPEINFO_INIT_PRIMITIVE(*info);
1006 /* typeinfos_init_from_methoddesc **********************************************
1008 Initialize an array of typeinfos and u1 TYPE_* values from a methoddesc.
1011 desc.............the methoddesc
1012 buflen...........number of parameters the buffer can hold
1013 twoword..........if true, use two parameter slots for two-word types
1016 *typebuf.........receives a TYPE_* constant for each parameter
1017 typebuf must be != NULL
1018 *infobuf.........receives a typeinfo for each parameter
1019 infobuf must be != NULL
1020 *returntype......receives a TYPE_* constant for the return type
1021 returntype may be NULL
1022 *returntypeinfo..receives a typeinfo for the return type
1023 returntypeinfo may be NULL
1026 true.............success
1027 false............an exception has been thrown
1030 If (according to BUFLEN) the buffers are to small to hold the
1031 parameter types, an internal error is thrown. This must be
1032 avoided by checking the number of parameters and allocating enough
1033 space before calling this function.
1035 *******************************************************************************/
1038 typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
1039 int buflen,bool twoword,
1040 u1 *returntype,typeinfo *returntypeinfo)
1045 TYPEINFO_ASSERT(desc);
1046 TYPEINFO_ASSERT(typebuf);
1047 TYPEINFO_ASSERT(infobuf);
1049 #ifdef TYPEINFO_VERBOSE
1050 fprintf(stderr,"typeinfos_init_from_methoddesc(");
1051 descriptor_debug_print_methoddesc(stderr,desc);
1052 fprintf(stderr,")\n");
1055 /* check arguments */
1056 for (i=0; i<desc->paramcount; ++i) {
1057 if (++args > buflen) {
1058 exceptions_throw_internalerror("Buffer too small for method arguments.");
1062 if (!typeinfo_init_from_typedesc(desc->paramtypes + i,typebuf++,infobuf++))
1065 if (twoword && (typebuf[-1] == TYPE_LNG || typebuf[-1] == TYPE_DBL)) {
1066 if (++args > buflen) {
1067 exceptions_throw_internalerror("Buffer too small for method arguments.");
1071 *typebuf++ = TYPE_VOID;
1072 TYPEINFO_INIT_PRIMITIVE(*infobuf);
1077 /* check returntype */
1079 if (!typeinfo_init_from_typedesc(&(desc->returntype),returntype,returntypeinfo))
1086 /* typedescriptor_init_from_typedesc *******************************************
1088 Initialize a typedescriptor from a typedesc.
1091 desc.............the typedesc
1094 *td..............receives the typedescriptor
1098 true.............success
1099 false............an exception has been thrown
1101 *******************************************************************************/
1104 typedescriptor_init_from_typedesc(typedescriptor *td,
1107 TYPEINFO_ASSERT(td);
1108 TYPEINFO_ASSERT(desc);
1110 td->type = desc->type;
1111 if (td->type == TYPE_ADR) {
1112 if (!typeinfo_init_class(&(td->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
1116 TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
1121 /* typeinfo_init_varinfo_from_typedesc *****************************************
1123 Initialize a varinfo from a typedesc.
1126 desc.............the typedesc
1129 *var.............receives the type
1133 true.............success
1134 false............an exception has been thrown
1136 *******************************************************************************/
1139 typeinfo_init_varinfo_from_typedesc(varinfo *var,
1142 TYPEINFO_ASSERT(var);
1143 TYPEINFO_ASSERT(desc);
1145 var->type = desc->type;
1146 if (var->type == TYPE_ADR) {
1147 if (!typeinfo_init_class(&(var->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
1151 TYPEINFO_INIT_PRIMITIVE(var->typeinfo);
1156 /* typeinfo_init_varinfos_from_methoddesc **************************************
1158 Initialize an array of varinfos from a methoddesc.
1161 desc.............the methoddesc
1162 buflen...........number of parameters the buffer can hold
1163 startindex.......the zero-based index of the first parameter to
1164 write to the array. In other words the number of
1165 parameters to skip at the beginning of the methoddesc.
1166 map..............map from parameter indices to varinfo indices
1167 (indexed like jitdata.local_map)
1170 *vars............array receiving the varinfos
1171 td[0] receives the type of the
1172 (startindex+1)th parameter of the method
1173 *returntype......receives the typedescriptor of the return type.
1174 returntype may be NULL
1177 true.............everything ok
1178 false............an exception has been thrown
1181 If (according to BUFLEN) the buffer is to small to hold the
1182 parameter types, an internal error is thrown. This must be
1183 avoided by checking the number of parameters and allocating enough
1184 space before calling this function.
1186 *******************************************************************************/
1189 typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
1191 int buflen, int startindex,
1193 typedescriptor *returntype)
1200 /* skip arguments */
1201 for (i=0; i<startindex; ++i) {
1203 if (IS_2_WORD_TYPE(desc->paramtypes[i].type))
1207 /* check arguments */
1208 for (i=startindex; i<desc->paramcount; ++i) {
1209 type = desc->paramtypes[i].type;
1210 varindex = map[5*slot + type];
1213 if (IS_2_WORD_TYPE(type))
1216 if (varindex == UNUSED)
1219 if (varindex >= buflen) {
1220 exceptions_throw_internalerror("Buffer too small for method arguments.");
1224 if (!typeinfo_init_varinfo_from_typedesc(vars + varindex, desc->paramtypes + i))
1228 /* check returntype */
1230 if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1237 /* typedescriptors_init_from_methoddesc ****************************************
1239 Initialize an array of typedescriptors from a methoddesc.
1242 desc.............the methoddesc
1243 buflen...........number of parameters the buffer can hold
1244 twoword..........if true, use two parameter slots for two-word types
1245 startindex.......the zero-based index of the first parameter to
1246 write to the array. In other words the number of
1247 parameters to skip at the beginning of the methoddesc.
1250 *td..............array receiving the typedescriptors.
1251 td[0] receives the typedescriptor of the
1252 (startindex+1)th parameter of the method
1253 *returntype......receives the typedescriptor of the return type.
1254 returntype may be NULL
1257 >= 0.............number of typedescriptors filled in TD
1258 -1...............an exception has been thrown
1261 If (according to BUFLEN) the buffer is to small to hold the
1262 parameter types, an internal error is thrown. This must be
1263 avoided by checking the number of parameters and allocating enough
1264 space before calling this function.
1266 *******************************************************************************/
1269 typedescriptors_init_from_methoddesc(typedescriptor *td,
1271 int buflen,bool twoword,int startindex,
1272 typedescriptor *returntype)
1277 /* check arguments */
1278 for (i=startindex; i<desc->paramcount; ++i) {
1279 if (++args > buflen) {
1280 exceptions_throw_internalerror("Buffer too small for method arguments.");
1284 if (!typedescriptor_init_from_typedesc(td,desc->paramtypes + i))
1288 if (twoword && (td[-1].type == TYPE_LNG || td[-1].type == TYPE_DBL)) {
1289 if (++args > buflen) {
1290 exceptions_throw_internalerror("Buffer too small for method arguments.");
1294 td->type = TYPE_VOID;
1295 TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
1300 /* check returntype */
1302 if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1309 /* typeinfo_init_component *****************************************************
1311 Initialize a typeinfo with the component type of a given array type.
1314 srcarray.........the typeinfo of the array type
1317 *dst.............receives the typeinfo of the component type
1320 true.............success
1321 false............an exception has been thrown
1323 *******************************************************************************/
1326 typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
1328 typeinfo_mergedlist *merged;
1330 TYPEINFO_ASSERT(srcarray);
1331 TYPEINFO_ASSERT(dst);
1333 if (TYPEINFO_IS_NULLTYPE(*srcarray)) {
1334 TYPEINFO_INIT_NULLTYPE(*dst);
1338 if (!TYPEINFO_IS_ARRAY(*srcarray)) {
1339 /* XXX should we make that a verify error? */
1340 exceptions_throw_internalerror("Trying to access component of non-array");
1344 /* save the mergedlist (maybe dst == srcarray) */
1346 merged = srcarray->merged;
1348 if (IS_CLASSREF(srcarray->typeclass)) {
1349 constant_classref *comp;
1350 comp = class_get_classref_component_of(srcarray->typeclass.ref);
1353 if (!typeinfo_init_class(dst,CLASSREF_OR_CLASSINFO(comp)))
1357 TYPEINFO_INIT_PRIMITIVE(*dst);
1363 if (!(srcarray->typeclass.cls->state & CLASS_LINKED)) {
1364 if (!link_class(srcarray->typeclass.cls)) {
1369 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl);
1370 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl->arraydesc);
1372 comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
1374 typeinfo_init_classinfo(dst,comp->class);
1376 TYPEINFO_INIT_PRIMITIVE(*dst);
1379 dst->merged = merged; /* XXX should we do a deep copy? */
1383 /* typeinfo_clone **************************************************************
1385 Create a deep copy of a typeinfo struct.
1388 src..............the typeinfo to copy
1391 *dest............receives the copy
1394 If src == dest this function is a nop.
1396 *******************************************************************************/
1399 typeinfo_clone(typeinfo *src,typeinfo *dest)
1402 classref_or_classinfo *srclist,*destlist;
1410 count = src->merged->count;
1411 TYPEINFO_ALLOCMERGED(dest->merged,count);
1412 dest->merged->count = count;
1414 srclist = src->merged->list;
1415 destlist = dest->merged->list;
1417 *destlist++ = *srclist++;
1421 /**********************************************************************/
1422 /* MISCELLANEOUS FUNCTIONS */
1423 /**********************************************************************/
1425 /* typeinfo_free ***************************************************************
1427 Free memory referenced by the given typeinfo. The typeinfo itself is not
1431 info.............the typeinfo
1433 *******************************************************************************/
1436 typeinfo_free(typeinfo *info)
1438 TYPEINFO_FREEMERGED_IF_ANY(info->merged);
1439 info->merged = NULL;
1442 /**********************************************************************/
1443 /* MERGING FUNCTIONS */
1444 /* The following functions are used to merge the types represented by */
1445 /* two typeinfo structures into one typeinfo structure. */
1446 /**********************************************************************/
1450 typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
1451 #ifdef TYPEINFO_VERBOSE
1452 fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
1453 fprintf(stderr,"Typeinfo x:\n");
1454 typeinfo_print(stderr,x,1);
1455 fprintf(stderr,"Typeinfo y:\n");
1456 typeinfo_print(stderr,y,1);
1460 exceptions_throw_verifyerror(m, str);
1463 /* Condition: clsx != clsy. */
1464 /* Returns: true if dest was changed (currently always true). */
1467 typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
1469 TYPEINFO_ASSERT(dest);
1470 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1471 TYPEINFO_ALLOCMERGED(dest->merged,2);
1472 dest->merged->count = 2;
1474 TYPEINFO_ASSERT(clsx.any != clsy.any);
1476 if (clsx.any < clsy.any) {
1477 dest->merged->list[0] = clsx;
1478 dest->merged->list[1] = clsy;
1481 dest->merged->list[0] = clsy;
1482 dest->merged->list[1] = clsx;
1488 /* Returns: true if dest was changed. */
1491 typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo cls)
1494 typeinfo_mergedlist *newmerged;
1495 classref_or_classinfo *mlist,*newlist;
1500 /* Check if cls is already in the mergedlist m. */
1502 if ((mlist++)->any == cls.any) { /* XXX check equal classrefs? */
1503 /* cls is in the list, so m is the resulting mergedlist */
1504 if (dest->merged == m)
1507 /* We have to copy the mergedlist */
1508 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1510 TYPEINFO_ALLOCMERGED(dest->merged,count);
1511 dest->merged->count = count;
1512 newlist = dest->merged->list;
1515 *newlist++ = *mlist++;
1521 /* Add cls to the mergedlist. */
1523 TYPEINFO_ALLOCMERGED(newmerged,count+1);
1524 newmerged->count = count+1;
1525 newlist = newmerged->list;
1528 if (mlist->any > cls.any)
1530 *newlist++ = *mlist++;
1535 *newlist++ = *mlist++;
1538 /* Put the new mergedlist into dest. */
1539 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1540 dest->merged = newmerged;
1545 /* Returns: true if dest was changed. */
1548 typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
1549 typeinfo_mergedlist *y)
1553 typeinfo_mergedlist *temp,*result;
1554 classref_or_classinfo *clsx,*clsy,*newlist;
1556 /* count the elements that will be in the resulting list */
1557 /* (Both lists are sorted, equal elements are counted only once.) */
1562 while (countx && county) {
1563 if (clsx->any == clsy->any) {
1569 else if (clsx->any < clsy->any) {
1579 count += countx + county;
1581 /* {The new mergedlist will have count entries.} */
1583 if ((x->count != count) && (y->count == count)) {
1584 temp = x; x = y; y = temp;
1586 /* {If one of x,y is already the result it is x.} */
1587 if (x->count == count) {
1588 /* x->merged is equal to the result */
1589 if (x == dest->merged)
1592 if (!dest->merged || dest->merged->count != count) {
1593 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1594 TYPEINFO_ALLOCMERGED(dest->merged,count);
1595 dest->merged->count = count;
1598 newlist = dest->merged->list;
1601 *newlist++ = *clsx++;
1606 /* {We have to merge two lists.} */
1608 /* allocate the result list */
1609 TYPEINFO_ALLOCMERGED(result,count);
1610 result->count = count;
1611 newlist = result->list;
1613 /* merge the sorted lists */
1618 while (countx && county) {
1619 if (clsx->any == clsy->any) {
1620 *newlist++ = *clsx++;
1625 else if (clsx->any < clsy->any) {
1626 *newlist++ = *clsx++;
1630 *newlist++ = *clsy++;
1635 *newlist++ = *clsx++;
1637 *newlist++ = *clsy++;
1639 /* replace the list in dest with the result list */
1640 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1641 dest->merged = result;
1646 /* typeinfo_merge_nonarrays ****************************************************
1648 Merge two non-array types.
1651 x................the first type
1652 y................the second type
1653 mergedx..........merged list of the first type, may be NULL
1654 mergedy..........merged list of the descond type, may be NULL
1657 *dest............receives the resulting merged list
1658 *result..........receives the resulting type
1661 typecheck_TRUE...*dest has been modified
1662 typecheck_FALSE..*dest has not been modified
1663 typecheck_FAIL...an exception has been thrown
1666 RESULT is an extra parameter so it can point to dest->typeclass or to
1669 *******************************************************************************/
1671 static typecheck_result
1672 typeinfo_merge_nonarrays(typeinfo *dest,
1673 classref_or_classinfo *result,
1674 classref_or_classinfo x,classref_or_classinfo y,
1675 typeinfo_mergedlist *mergedx,
1676 typeinfo_mergedlist *mergedy)
1678 classref_or_classinfo t;
1679 classinfo *tcls,*common;
1680 typeinfo_mergedlist *tmerged;
1686 TYPEINFO_ASSERT(dest && result && x.any && y.any);
1687 TYPEINFO_ASSERT(x.cls != pseudo_class_Null);
1688 TYPEINFO_ASSERT(y.cls != pseudo_class_Null);
1689 TYPEINFO_ASSERT(x.cls != pseudo_class_New);
1690 TYPEINFO_ASSERT(y.cls != pseudo_class_New);
1692 /*--------------------------------------------------*/
1694 /*--------------------------------------------------*/
1696 /* Common case 1: x and y are the same class or class reference */
1697 /* (This case is very simple unless *both* x and y really represent
1698 * merges of subclasses of clsx==clsy.)
1700 if ( (x.any == y.any) && (!mergedx || !mergedy) ) {
1702 /* DEBUG */ /* log_text("return simple x"); */
1703 changed = (dest->merged != NULL);
1704 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1705 dest->merged = NULL;
1707 /* DEBUG */ /* log_text("returning"); */
1711 xname = (IS_CLASSREF(x)) ? x.ref->name : x.cls->name;
1712 yname = (IS_CLASSREF(y)) ? y.ref->name : y.cls->name;
1714 /* Common case 2: xname == yname, at least one unresolved */
1715 if ((IS_CLASSREF(x) || IS_CLASSREF(y)) && (xname == yname))
1717 /* use the loaded one if any */
1718 if (!IS_CLASSREF(y))
1720 goto return_simple_x;
1723 /*--------------------------------------------------*/
1724 /* non-trivial cases */
1725 /*--------------------------------------------------*/
1727 #ifdef TYPEINFO_VERBOSE
1730 fprintf(stderr,"merge_nonarrays:\n");
1731 fprintf(stderr," ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,xname);fprintf(stderr,"\n");
1732 fprintf(stderr," ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,yname);fprintf(stderr,"\n");
1734 typeinfo_init_class(&dbgx,x);
1735 dbgx.merged = mergedx;
1736 typeinfo_init_class(&dbgy,y);
1737 dbgy.merged = mergedy;
1738 typeinfo_print(stderr,&dbgx,4);
1739 fprintf(stderr," with:\n");
1740 typeinfo_print(stderr,&dbgy,4);
1744 TYPEINFO_ASSERT(IS_CLASSREF(x) || (x.cls->state & CLASS_LOADED));
1745 TYPEINFO_ASSERT(IS_CLASSREF(y) || (y.cls->state & CLASS_LOADED));
1747 /* If y is unresolved or an interface, swap x and y. */
1748 if (IS_CLASSREF(y) || (!IS_CLASSREF(x) && y.cls->flags & ACC_INTERFACE))
1750 t = x; x = y; y = t;
1751 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1754 /* {We know: If only one of x,y is unresolved it is x,} */
1755 /* { If both x,y are resolved and only one of x,y is an interface it is x.} */
1757 if (IS_CLASSREF(x)) {
1758 /* {We know: x and y have different class names} */
1760 /* Check if we are merging an unresolved type with java.lang.Object */
1761 if (y.cls == class_java_lang_Object && !mergedy) {
1763 goto return_simple_x;
1766 common = class_java_lang_Object;
1767 goto merge_with_simple_x;
1770 /* {We know: both x and y are resolved} */
1771 /* {We know: If only one of x,y is an interface it is x.} */
1773 TYPEINFO_ASSERT(!IS_CLASSREF(x) && !IS_CLASSREF(y));
1774 TYPEINFO_ASSERT(x.cls->state & CLASS_LOADED);
1775 TYPEINFO_ASSERT(y.cls->state & CLASS_LOADED);
1777 /* Handle merging of interfaces: */
1778 if (x.cls->flags & ACC_INTERFACE) {
1779 /* {x.cls is an interface and mergedx == NULL.} */
1781 if (y.cls->flags & ACC_INTERFACE) {
1782 /* We are merging two interfaces. */
1783 /* {mergedy == NULL} */
1785 /* {We know that x.cls!=y.cls (see common case at beginning.)} */
1786 result->cls = class_java_lang_Object;
1787 return typeinfo_merge_two(dest,x,y);
1790 /* {We know: x is an interface, y is a class.} */
1792 /* Check if we are merging an interface with java.lang.Object */
1793 if (y.cls == class_java_lang_Object && !mergedy) {
1795 goto return_simple_x;
1798 /* If the type y implements x then the result of the merge
1799 * is x regardless of mergedy.
1802 /* we may have to link the classes */
1803 if (!(x.cls->state & CLASS_LINKED))
1804 if (!link_class(x.cls))
1805 return typecheck_FAIL;
1806 if (!(y.cls->state & CLASS_LINKED))
1807 if (!link_class(y.cls))
1808 return typecheck_FAIL;
1810 TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
1811 TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
1813 if (CLASSINFO_IMPLEMENTS_INTERFACE(y.cls,x.cls->index))
1815 /* y implements x, so the result of the merge is x. */
1816 goto return_simple_x;
1819 r = mergedlist_implements_interface(mergedy,x.cls);
1820 if (r == typecheck_FAIL)
1822 if (r == typecheck_TRUE)
1824 /* y implements x, so the result of the merge is x. */
1825 goto return_simple_x;
1828 /* {We know: x is an interface, the type y a class or a merge
1829 * of subclasses and is not guaranteed to implement x.} */
1831 common = class_java_lang_Object;
1832 goto merge_with_simple_x;
1835 /* {We know: x and y are classes (not interfaces).} */
1837 /* we may have to link the classes */
1838 if (!(x.cls->state & CLASS_LINKED))
1839 if (!link_class(x.cls))
1840 return typecheck_FAIL;
1841 if (!(y.cls->state & CLASS_LINKED))
1842 if (!link_class(y.cls))
1843 return typecheck_FAIL;
1845 TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
1846 TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
1848 /* If *x is deeper in the inheritance hierarchy swap x and y. */
1849 if (x.cls->index > y.cls->index) {
1850 t = x; x = y; y = t;
1851 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1854 /* {We know: y is at least as deep in the hierarchy as x.} */
1856 /* Find nearest common anchestor for the classes. */
1859 while (tcls->index > common->index)
1860 tcls = tcls->super.cls;
1861 while (common != tcls) {
1862 common = common->super.cls;
1863 tcls = tcls->super.cls;
1866 /* {common == nearest common anchestor of x and y.} */
1868 /* If x.cls==common and x is a whole class (not a merge of subclasses)
1869 * then the result of the merge is x.
1871 if (x.cls == common && !mergedx) {
1872 goto return_simple_x;
1876 result->cls = common;
1878 return typeinfo_merge_mergedlists(dest,mergedx,mergedy);
1880 return typeinfo_merge_add(dest,mergedx,y);
1883 merge_with_simple_x:
1884 result->cls = common;
1886 return typeinfo_merge_add(dest,mergedy,x);
1888 return typeinfo_merge_two(dest,x,y);
1891 /* typeinfo_merge **************************************************************
1896 m................method for exception messages
1897 dest.............the first type
1898 y................the second type
1901 *dest............receives the result of the merge
1904 typecheck_TRUE...*dest has been modified
1905 typecheck_FALSE..*dest has not been modified
1906 typecheck_FAIL...an exception has been thrown
1909 1) *dest must be a valid initialized typeinfo
1912 *******************************************************************************/
1915 typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y)
1919 classref_or_classinfo common;
1920 classref_or_classinfo elementclass;
1926 /*--------------------------------------------------*/
1928 /*--------------------------------------------------*/
1930 /* Merging something with itself is a nop */
1932 return typecheck_FALSE;
1934 /* Merging two returnAddress types is ok. */
1935 /* Merging two different returnAddresses never happens, as the verifier */
1936 /* keeps them separate in order to check all the possible return paths */
1937 /* from JSR subroutines. */
1938 if (!dest->typeclass.any && !y->typeclass.any) {
1939 TYPEINFO_ASSERT(TYPEINFO_RETURNADDRESS(*dest) == TYPEINFO_RETURNADDRESS(*y));
1940 return typecheck_FALSE;
1943 /* Primitive types cannot be merged with reference types */
1944 /* This must be checked before calls to typeinfo_merge. */
1945 TYPEINFO_ASSERT(dest->typeclass.any && y->typeclass.any);
1947 /* handle uninitialized object types */
1948 if (TYPEINFO_IS_NEWOBJECT(*dest) || TYPEINFO_IS_NEWOBJECT(*y)) {
1949 if (!TYPEINFO_IS_NEWOBJECT(*dest) || !TYPEINFO_IS_NEWOBJECT(*y)) {
1950 typeinfo_merge_error(m,"Trying to merge uninitialized object type.",dest,y);
1951 return typecheck_FAIL;
1953 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*dest) != TYPEINFO_NEWOBJECT_INSTRUCTION(*y)) {
1954 typeinfo_merge_error(m,"Trying to merge different uninitialized objects.",dest,y);
1955 return typecheck_FAIL;
1957 /* the same uninitialized object -- no change */
1958 return typecheck_FALSE;
1961 /*--------------------------------------------------*/
1963 /*--------------------------------------------------*/
1965 /* Common case: dest and y are the same class or class reference */
1966 /* (This case is very simple unless *both* dest and y really represent
1967 * merges of subclasses of class dest==class y.)
1969 if ((dest->typeclass.any == y->typeclass.any) && (!dest->merged || !y->merged)) {
1971 changed = (dest->merged != NULL);
1972 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1973 dest->merged = NULL;
1977 /* Handle null types: */
1978 if (TYPEINFO_IS_NULLTYPE(*y)) {
1979 return typecheck_FALSE;
1981 if (TYPEINFO_IS_NULLTYPE(*dest)) {
1982 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1983 TYPEINFO_CLONE(*y,*dest);
1984 return typecheck_TRUE;
1987 /* Common case: two types with the same name, at least one unresolved */
1988 if (IS_CLASSREF(dest->typeclass)) {
1989 if (IS_CLASSREF(y->typeclass)) {
1990 if (dest->typeclass.ref->name == y->typeclass.ref->name)
1994 /* XXX should we take y instead of dest here? */
1995 if (dest->typeclass.ref->name == y->typeclass.cls->name)
2000 if (IS_CLASSREF(y->typeclass)
2001 && (dest->typeclass.cls->name == y->typeclass.ref->name))
2007 /*--------------------------------------------------*/
2008 /* non-trivial cases */
2009 /*--------------------------------------------------*/
2011 #ifdef TYPEINFO_VERBOSE
2012 fprintf(stderr,"merge:\n");
2013 typeinfo_print(stderr,dest,4);
2014 typeinfo_print(stderr,y,4);
2017 /* This function uses x internally, so x and y can be swapped
2018 * without changing dest. */
2022 /* Handle merging of arrays: */
2023 if (TYPEINFO_IS_ARRAY(*x) && TYPEINFO_IS_ARRAY(*y)) {
2025 /* Make x the one with lesser dimension */
2026 if (x->dimension > y->dimension) {
2027 tmp = x; x = y; y = tmp;
2030 /* If one array (y) has higher dimension than the other,
2031 * interpret it as an array (same dim. as x) of Arraystubs. */
2032 if (x->dimension < y->dimension) {
2033 dimension = x->dimension;
2034 elementtype = ARRAYTYPE_OBJECT;
2035 elementclass.cls = pseudo_class_Arraystub;
2038 dimension = y->dimension;
2039 elementtype = y->elementtype;
2040 elementclass = y->elementclass;
2043 /* {The arrays are of the same dimension.} */
2045 if (x->elementtype != elementtype) {
2046 /* Different element types are merged, so the resulting array
2047 * type has one accessible dimension less. */
2048 if (--dimension == 0) {
2049 common.cls = pseudo_class_Arraystub;
2051 elementclass.any = NULL;
2054 common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub,true);
2056 exceptions_throw_internalerror("XXX Coult not create array class");
2057 return typecheck_FAIL;
2060 elementtype = ARRAYTYPE_OBJECT;
2061 elementclass.cls = pseudo_class_Arraystub;
2065 /* {The arrays have the same dimension and elementtype.} */
2067 if (elementtype == ARRAYTYPE_OBJECT) {
2068 /* The elements are references, so their respective
2069 * types must be merged.
2071 r = typeinfo_merge_nonarrays(dest,
2075 x->merged,y->merged);
2076 TYPEINFO_ASSERT(r != typecheck_MAYBE);
2077 if (r == typecheck_FAIL)
2081 /* DEBUG */ /* log_text("finding resulting array class: "); */
2082 if (IS_CLASSREF(elementclass))
2083 common.ref = class_get_classref_multiarray_of(dimension,elementclass.ref);
2085 common.cls = class_multiarray_of(dimension,elementclass.cls,true);
2087 exceptions_throw_internalerror("XXX Coult not create array class");
2088 return typecheck_FAIL;
2091 /* DEBUG */ /* utf_display_printable_ascii(common->name); printf("\n"); */
2094 common.any = y->typeclass.any;
2099 /* {We know that at least one of x or y is no array, so the
2100 * result cannot be an array.} */
2102 r = typeinfo_merge_nonarrays(dest,
2104 x->typeclass,y->typeclass,
2105 x->merged,y->merged);
2106 TYPEINFO_ASSERT(r != typecheck_MAYBE);
2107 if (r == typecheck_FAIL)
2113 elementclass.any = NULL;
2116 /* Put the new values into dest if neccessary. */
2118 if (dest->typeclass.any != common.any) {
2119 dest->typeclass.any = common.any;
2122 if (dest->dimension != dimension) {
2123 dest->dimension = dimension;
2126 if (dest->elementtype != elementtype) {
2127 dest->elementtype = elementtype;
2130 if (dest->elementclass.any != elementclass.any) {
2131 dest->elementclass.any = elementclass.any;
2137 #endif /* ENABLE_VERIFER */
2140 /**********************************************************************/
2141 /* DEBUGGING HELPERS */
2142 /**********************************************************************/
2144 #ifdef TYPEINFO_DEBUG
2148 typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
2150 if (a->any == b->any) return 0;
2151 if (a->any < b->any) return -1;
2156 typeinfo_test_parse(typeinfo *info,char *str)
2163 utf *desc = utf_new_char(str);
2165 num = typeinfo_count_method_args(desc,false);
2167 typebuf = DMNEW(u1,num);
2168 infobuf = DMNEW(typeinfo,num);
2170 typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
2173 TYPEINFO_ALLOCMERGED(info->merged,num);
2174 info->merged->count = num;
2176 for (i=0; i<num; ++i) {
2177 if (typebuf[i] != TYPE_ADR) {
2178 log_text("non-reference type in mergedlist");
2182 info->merged->list[i].any = infobuf[i].typeclass.any;
2184 qsort(info->merged->list,num,sizeof(classref_or_classinfo),
2185 (int(*)(const void *,const void *))&typeinfo_test_compare);
2188 typeinfo_init_from_method_args(desc,NULL,NULL,0,false,
2194 #define TYPEINFO_TEST_BUFLEN 4000
2197 typeinfo_equal(typeinfo *x,typeinfo *y)
2201 if (x->typeclass.any != y->typeclass.any) return false;
2202 if (x->dimension != y->dimension) return false;
2204 if (x->elementclass.any != y->elementclass.any) return false;
2205 if (x->elementtype != y->elementtype) return false;
2208 if (TYPEINFO_IS_NEWOBJECT(*x))
2209 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*x)
2210 != TYPEINFO_NEWOBJECT_INSTRUCTION(*y))
2213 if (x->merged || y->merged) {
2214 if (!(x->merged && y->merged)) return false;
2215 if (x->merged->count != y->merged->count) return false;
2216 for (i=0; i<x->merged->count; ++i)
2217 if (x->merged->list[i].any != y->merged->list[i].any)
2224 typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
2227 bool changed,changed_should_be;
2230 TYPEINFO_CLONE(*a,dest);
2233 typeinfo_print_short(stdout,&dest);
2235 typeinfo_print_short(stdout,b);
2238 r = typeinfo_merge(NULL,&dest,b);
2239 if (r == typecheck_FAIL) {
2240 printf("EXCEPTION\n");
2243 changed = (r) ? 1 : 0;
2244 changed_should_be = (!typeinfo_equal(&dest,a)) ? 1 : 0;
2246 printf(" %s\n",(changed) ? "changed" : "=");
2248 if (typeinfo_equal(&dest,result)) {
2250 typeinfo_print_short(stdout,&dest);
2252 if (changed != changed_should_be) {
2253 printf("WRONG RETURN VALUE!\n");
2259 typeinfo_print_short(stdout,&dest);
2261 printf("SHOULD BE ");
2262 typeinfo_print_short(stdout,result);
2270 typeinfo_inc_dimension(typeinfo *info)
2272 if (info->dimension++ == 0) {
2273 info->elementtype = ARRAYTYPE_OBJECT;
2274 info->elementclass = info->typeclass;
2276 info->typeclass = class_array_of(info->typeclass,true);
2280 #define TYPEINFO_TEST_MAXDIM 10
2283 typeinfo_testrun(char *filename)
2285 char buf[TYPEINFO_TEST_BUFLEN];
2286 char bufa[TYPEINFO_TEST_BUFLEN];
2287 char bufb[TYPEINFO_TEST_BUFLEN];
2288 char bufc[TYPEINFO_TEST_BUFLEN];
2292 FILE *file = fopen(filename,"rt");
2296 log_text("could not open typeinfo test file");
2300 while (fgets(buf,TYPEINFO_TEST_BUFLEN,file)) {
2301 if (buf[0] == '#' || !strlen(buf))
2304 res = sscanf(buf,"%s\t%s\t%s\n",bufa,bufb,bufc);
2305 if (res != 3 || !strlen(bufa) || !strlen(bufb) || !strlen(bufc)) {
2306 log_text("Invalid line in typeinfo test file (none of empty, comment or test)");
2311 typeinfo_test_parse(&a,bufa);
2312 typeinfo_test_parse(&b,bufb);
2313 typeinfo_test_parse(&c,bufc);
2318 typeinfo_testmerge(&a,&b,&c,&failed); /* check result */
2319 typeinfo_testmerge(&b,&a,&c,&failed); /* check commutativity */
2321 if (TYPEINFO_IS_NULLTYPE(a)) break;
2322 if (TYPEINFO_IS_NULLTYPE(b)) break;
2323 if (TYPEINFO_IS_NULLTYPE(c)) break;
2325 maxdim = a.dimension;
2326 if (b.dimension > maxdim) maxdim = b.dimension;
2327 if (c.dimension > maxdim) maxdim = c.dimension;
2330 if (maxdim < TYPEINFO_TEST_MAXDIM) {
2331 typeinfo_inc_dimension(&a);
2332 typeinfo_inc_dimension(&b);
2333 typeinfo_inc_dimension(&c);
2335 } while (maxdim < TYPEINFO_TEST_MAXDIM);
2342 fprintf(stderr,"Failed typeinfo_merge tests: %d\n",failed);
2343 log_text("Failed test");
2351 log_text("Running typeinfo test file...");
2352 typeinfo_testrun("typeinfo.tst");
2353 log_text("Finished typeinfo test file.");
2358 typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc)
2360 typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
2364 #define TYPEINFO_MAXINDENT 80
2367 typeinfo_print_class(FILE *file,classref_or_classinfo c)
2369 /*fprintf(file,"<class %p>",c.any);*/
2372 fprintf(file,"<null>");
2375 if (IS_CLASSREF(c)) {
2376 fprintf(file,"<ref>");
2377 utf_fprint_printable_ascii(file,c.ref->name);
2380 utf_fprint_printable_ascii(file,c.cls->name);
2386 typeinfo_print(FILE *file,typeinfo *info,int indent)
2389 char ind[TYPEINFO_MAXINDENT + 1];
2393 if (indent > TYPEINFO_MAXINDENT) indent = TYPEINFO_MAXINDENT;
2395 for (i=0; i<indent; ++i)
2399 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2400 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2402 fprintf(file,"%sreturnAddress (L%03d)\n",ind,bptr->nr);
2404 fprintf(file,"%sprimitive\n",ind);
2408 if (TYPEINFO_IS_NULLTYPE(*info)) {
2409 fprintf(file,"%snull\n",ind);
2413 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2414 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2416 fprintf(file,"%sNEW(%p):",ind,(void*)ins);
2417 typeinfo_print_class(file,ins[-1].sx.val.c);
2421 fprintf(file,"%sNEW(this)",ind);
2426 fprintf(file,"%sClass: ",ind);
2427 typeinfo_print_class(file,info->typeclass);
2430 if (TYPEINFO_IS_ARRAY(*info)) {
2431 fprintf(file,"%sDimension: %d",ind,(int)info->dimension);
2432 fprintf(file,"\n%sElements: ",ind);
2433 switch (info->elementtype) {
2434 case ARRAYTYPE_INT : fprintf(file,"int\n"); break;
2435 case ARRAYTYPE_LONG : fprintf(file,"long\n"); break;
2436 case ARRAYTYPE_FLOAT : fprintf(file,"float\n"); break;
2437 case ARRAYTYPE_DOUBLE : fprintf(file,"double\n"); break;
2438 case ARRAYTYPE_BYTE : fprintf(file,"byte\n"); break;
2439 case ARRAYTYPE_CHAR : fprintf(file,"char\n"); break;
2440 case ARRAYTYPE_SHORT : fprintf(file,"short\n"); break;
2441 case ARRAYTYPE_BOOLEAN : fprintf(file,"boolean\n"); break;
2443 case ARRAYTYPE_OBJECT:
2444 typeinfo_print_class(file,info->elementclass);
2449 fprintf(file,"INVALID ARRAYTYPE!\n");
2454 fprintf(file,"%sMerged: ",ind);
2455 for (i=0; i<info->merged->count; ++i) {
2456 if (i) fprintf(file,", ");
2457 typeinfo_print_class(file,info->merged->list[i]);
2464 typeinfo_print_short(FILE *file,typeinfo *info)
2470 /*fprintf(file,"<typeinfo %p>",info);*/
2473 fprintf(file,"(typeinfo*)NULL");
2477 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2478 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2480 fprintf(file,"ret(L%03d)",bptr->nr);
2482 fprintf(file,"primitive");
2486 if (TYPEINFO_IS_NULLTYPE(*info)) {
2487 fprintf(file,"null");
2491 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2492 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2494 /*fprintf(file,"<ins %p>",ins);*/
2495 fprintf(file,"NEW(%p):",(void*)ins);
2496 typeinfo_print_class(file,ins[-1].sx.val.c);
2499 fprintf(file,"NEW(this)");
2503 typeinfo_print_class(file,info->typeclass);
2507 for (i=0; i<info->merged->count; ++i) {
2508 if (i) fprintf(file,",");
2509 typeinfo_print_class(file,info->merged->list[i]);
2516 typeinfo_print_type(FILE *file,int type,typeinfo *info)
2519 case TYPE_VOID: fprintf(file,"V"); break;
2520 case TYPE_INT: fprintf(file,"I"); break;
2521 case TYPE_FLT: fprintf(file,"F"); break;
2522 case TYPE_DBL: fprintf(file,"D"); break;
2523 case TYPE_LNG: fprintf(file,"J"); break;
2524 case TYPE_RET: fprintf(file,"R:"); /* FALLTHROUGH! */
2526 typeinfo_print_short(file,info);
2535 typedescriptor_print(FILE *file,typedescriptor *td)
2537 typeinfo_print_type(file,td->type,&(td->typeinfo));
2541 typevector_print(FILE *file,varinfo *vec,int size)
2545 for (i=0; i<size; ++i) {
2546 fprintf(file," %d=",i);
2547 typeinfo_print_type(file, vec[i].type, &(vec[i].typeinfo));
2551 #endif /* TYPEINFO_DEBUG */
2555 * These are local overrides for various environment variables in Emacs.
2556 * Please do not remove this and leave it at the end of the file, where
2557 * Emacs will automagically detect them.
2558 * ---------------------------------------------------------------------
2561 * indent-tabs-mode: t
2565 * vim:noexpandtab:sw=4:ts=4: