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
33 #include "mm/memory.h"
35 #include "toolbox/logging.h"
38 #include "vm/exceptions.h"
39 #include "vm/primitive.h"
40 #include "vm/resolve.h"
42 #include "vm/jit/jit.h"
43 #include "vm/jit/verify/typeinfo.h"
45 #include "vmcore/class.h"
46 #include "vmcore/descriptor.h"
47 #include "vmcore/loader.h"
50 /* check if a linked class is an array class. Only use for linked classes! */
51 #define CLASSINFO_IS_ARRAY(clsinfo) ((clsinfo)->vftbl->arraydesc != NULL)
53 /* check if a linked class implements the interface with the given index */
54 #define CLASSINFO_IMPLEMENTS_INTERFACE(cls,index) \
55 ( ((index) < (cls)->vftbl->interfacetablelength) \
56 && ( (cls)->vftbl->interfacetable[-(index)] != NULL ) )
58 /******************************************************************************/
60 /******************************************************************************/
63 #define TYPEINFO_ASSERT(cond) assert(cond)
65 #define TYPEINFO_ASSERT(cond)
68 /**********************************************************************/
69 /* TYPEVECTOR FUNCTIONS */
70 /**********************************************************************/
72 #if defined(ENABLE_VERIFIER)
74 /* typevector_copy *************************************************************
76 Return a copy of the given typevector.
79 src..............typevector set to copy, must be != NULL
80 size.............number of elements per typevector
83 a pointer to the new typevector set
85 *******************************************************************************/
88 typevector_copy(varinfo *src, int size)
94 dst = DNEW_TYPEVECTOR(size);
95 memcpy(dst,src,TYPEVECTOR_SIZE(size));
100 /* typevector_copy_inplace *****************************************************
102 Copy a typevector to a given destination.
105 src..............typevector to copy, must be != NULL
106 dst..............destination to write the copy to
107 size.............number of elements per typevector
109 *******************************************************************************/
112 typevector_copy_inplace(varinfo *src,varinfo *dst,int size)
114 memcpy(dst,src,TYPEVECTOR_SIZE(size));
117 /* typevector_checktype ********************************************************
119 Check if the typevector contains a given type at a given index.
122 vec..............typevector set, must be != NULL
123 index............index of component to check
124 type.............TYPE_* constant to check against
127 true if the typevector contains TYPE at INDEX,
130 *******************************************************************************/
133 typevector_checktype(varinfo *vec,int index,int type)
135 TYPEINFO_ASSERT(vec);
137 return vec[index].type == type;
140 /* typevector_checkreference ***************************************************
142 Check if the typevector contains a reference at a given index.
145 vec..............typevector, must be != NULL
146 index............index of component to check
149 true if the typevector contains a reference at INDEX,
152 *******************************************************************************/
155 typevector_checkreference(varinfo *vec, int index)
157 TYPEINFO_ASSERT(vec);
158 return TYPEDESC_IS_REFERENCE(vec[index]);
161 /* typevectorset_checkretaddr **************************************************
163 Check if the typevectors contains a returnAddress at a given index.
166 vec..............typevector, must be != NULL
167 index............index of component to check
170 true if the typevector contains a returnAddress at INDEX,
173 *******************************************************************************/
176 typevector_checkretaddr(varinfo *vec,int index)
178 TYPEINFO_ASSERT(vec);
179 return TYPEDESC_IS_RETURNADDRESS(vec[index]);
182 /* typevector_store ************************************************************
184 Store a type at a given index in the typevector.
187 vec..............typevector set, must be != NULL
188 index............index of component to set
189 type.............TYPE_* constant of type to set
190 info.............typeinfo of type to set, may be NULL,
193 *******************************************************************************/
196 typevector_store(varinfo *vec,int index,int type,typeinfo *info)
198 TYPEINFO_ASSERT(vec);
200 vec[index].type = type;
202 TYPEINFO_COPY(*info,vec[index].typeinfo);
205 /* typevector_store_retaddr ****************************************************
207 Store a returnAddress type at a given index in the typevector.
210 vec..............typevector set, must be != NULL
211 index............index of component to set
212 info.............typeinfo of the returnAddress.
214 *******************************************************************************/
217 typevector_store_retaddr(varinfo *vec,int index,typeinfo *info)
219 TYPEINFO_ASSERT(vec);
220 TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
222 vec[index].type = TYPE_ADR;
223 TYPEINFO_INIT_RETURNADDRESS(vec[index].typeinfo,
224 TYPEINFO_RETURNADDRESS(*info));
227 /* typevector_init_object ******************************************************
229 Replace all uninitialized object types in the typevector set which were
230 created by the given instruction by initialized object types.
233 set..............typevector set
234 ins..............instruction which created the uninitialized object type
235 initclass........class of the initialized object type to set
236 size.............number of elements per typevector
239 true.............success
240 false............an exception has been thrown
242 XXX maybe we should do the lazy resolving before calling this function
244 *******************************************************************************/
247 typevector_init_object(varinfo *set,void *ins,
248 classref_or_classinfo initclass,
253 for (i=0; i<size; ++i) {
254 if (set[i].type == TYPE_ADR
255 && TYPEINFO_IS_NEWOBJECT(set[i].typeinfo)
256 && TYPEINFO_NEWOBJECT_INSTRUCTION(set[i].typeinfo) == ins)
258 if (!typeinfo_init_class(&(set[i].typeinfo),initclass))
265 /* typevector_merge ************************************************************
267 Merge a typevector with another one.
268 The given typevectors must have the same number of components.
271 m................method for exception messages
272 dst..............the first typevector
273 y................the second typevector
274 size.............number of elements per typevector
277 *dst.............the resulting typevector
280 typecheck_TRUE...dst has been modified
281 typecheck_FALSE..dst has not been modified
282 typecheck_FAIL...an exception has been thrown
284 *******************************************************************************/
287 typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size)
289 bool changed = false;
295 if (a->type != TYPE_VOID && a->type != b->type) {
299 else if (a->type == TYPE_ADR) {
300 if (TYPEINFO_IS_PRIMITIVE(a->typeinfo)) {
301 /* 'a' is a returnAddress */
302 if (!TYPEINFO_IS_PRIMITIVE(b->typeinfo)
303 || (TYPEINFO_RETURNADDRESS(a->typeinfo)
304 != TYPEINFO_RETURNADDRESS(b->typeinfo)))
311 /* 'a' is a reference */
312 if (TYPEINFO_IS_PRIMITIVE(b->typeinfo)) {
317 /* two reference types are merged. There cannot be */
318 /* a merge error. In the worst case we get j.l.O. */
319 r = typeinfo_merge(m,&(a->typeinfo),&(b->typeinfo));
320 if (r == typecheck_FAIL)
332 /**********************************************************************/
333 /* READ-ONLY FUNCTIONS */
334 /* The following functions don't change typeinfo data. */
335 /**********************************************************************/
337 /* typeinfo_is_array ***********************************************************
339 Check whether a typeinfo describes an array type.
342 info.............the typeinfo, must be != NULL
345 true if INFO describes an array type.
347 *******************************************************************************/
350 typeinfo_is_array(typeinfo *info)
352 TYPEINFO_ASSERT(info);
353 return TYPEINFO_IS_ARRAY(*info);
356 /* typeinfo_is_primitive_array *************************************************
358 Check whether a typeinfo describes a primitive array type.
361 info.............the typeinfo, must be != NULL
364 true if INFO describes an array of a primitive type.
366 *******************************************************************************/
369 typeinfo_is_primitive_array(typeinfo *info,int arraytype)
371 TYPEINFO_ASSERT(info);
372 return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
375 /* typeinfo_is_array_of_refs ***************************************************
377 Check whether a typeinfo describes an array of references type.
380 info.............the typeinfo, must be != NULL
383 true if INFO describes an array of a refrence type.
385 *******************************************************************************/
388 typeinfo_is_array_of_refs(typeinfo *info)
390 TYPEINFO_ASSERT(info);
391 return TYPEINFO_IS_ARRAY_OF_REFS(*info);
394 /* interface_extends_interface *************************************************
396 Check if a resolved interface extends a given resolved interface.
399 cls..............the interface, must be linked
400 interf...........the interface to check against
403 true.............CLS extends INTERF
404 false............CLS does not extend INTERF
406 *******************************************************************************/
409 interface_extends_interface(classinfo *cls,classinfo *interf)
413 TYPEINFO_ASSERT(cls);
414 TYPEINFO_ASSERT(interf);
415 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
416 TYPEINFO_ASSERT((cls->flags & ACC_INTERFACE) != 0);
417 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
419 /* first check direct superinterfaces */
420 for (i=0; i<cls->interfacescount; ++i) {
421 if (cls->interfaces[i] == interf)
425 /* check indirect superinterfaces */
426 for (i=0; i<cls->interfacescount; ++i) {
427 if (interface_extends_interface(cls->interfaces[i],interf))
434 /* classinfo_implements_interface **********************************************
436 Check if a resolved class implements a given resolved interface.
439 cls..............the class
440 interf...........the interface
443 typecheck_TRUE...CLS implements INTERF
444 typecheck_FALSE..CLS does not implement INTERF
445 typecheck_FAIL...an exception has been thrown
447 *******************************************************************************/
449 static typecheck_result
450 classinfo_implements_interface(classinfo *cls,classinfo *interf)
452 TYPEINFO_ASSERT(cls);
453 TYPEINFO_ASSERT(interf);
454 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
456 if (!(cls->state & CLASS_LINKED))
457 if (!link_class(cls))
458 return typecheck_FAIL;
460 if (cls->flags & ACC_INTERFACE) {
461 /* cls is an interface */
463 return typecheck_TRUE;
465 /* check superinterfaces */
466 return interface_extends_interface(cls,interf);
469 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
470 return CLASSINFO_IMPLEMENTS_INTERFACE(cls,interf->index);
473 /* mergedlist_implements_interface *********************************************
475 Check if all the classes in a given merged list implement a given resolved
479 merged...........the list of merged class types
480 interf...........the interface to check against
483 typecheck_TRUE...all classes implement INTERF
484 typecheck_FALSE..there is at least one class that does not implement
486 typecheck_MAYBE..check cannot be performed now because of unresolved
488 typecheck_FAIL...an exception has been thrown
490 *******************************************************************************/
492 static typecheck_result
493 mergedlist_implements_interface(typeinfo_mergedlist *merged,
497 classref_or_classinfo *mlist;
500 TYPEINFO_ASSERT(interf);
501 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
503 /* Check if there is an non-empty mergedlist. */
505 return typecheck_FALSE;
507 /* If all classinfos in the (non-empty) merged array implement the
508 * interface return true, otherwise false.
510 mlist = merged->list;
513 if (IS_CLASSREF(*mlist)) {
514 return typecheck_MAYBE;
516 r = classinfo_implements_interface((mlist++)->cls,interf);
517 if (r != typecheck_TRUE)
520 return typecheck_TRUE;
523 /* merged_implements_interface *************************************************
525 Check if a possible merged type implements a given resolved interface
529 typeclass........(common) class of the (merged) type
530 merged...........the list of merged class types
531 interf...........the interface to check against
534 typecheck_TRUE...the type implement INTERF
535 typecheck_FALSE..the type does not implement INTERF
536 typecheck_MAYBE..check cannot be performed now because of unresolved
538 typecheck_FAIL...an exception has been thrown
540 *******************************************************************************/
542 static typecheck_result
543 merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
548 /* primitive types don't support interfaces. */
550 return typecheck_FALSE;
552 /* the null type can be cast to any interface type. */
553 if (typeclass == pseudo_class_Null)
554 return typecheck_TRUE;
556 /* check if typeclass implements the interface. */
557 r = classinfo_implements_interface(typeclass,interf);
558 if (r != typecheck_FALSE)
561 /* check the mergedlist */
563 return typecheck_FALSE;
564 return mergedlist_implements_interface(merged,interf);
567 /* merged_is_subclass **********************************************************
569 Check if a possible merged type is a subclass of a given class.
570 A merged type is a subclass of a class C if all types in the merged list
571 are subclasses of C. A sufficient condition for this is that the
572 common type of the merged type is a subclass of C.
575 typeclass........(common) class of the (merged) type
576 MUST be a loaded and linked class
577 merged...........the list of merged class types
578 cls..............the class to theck against
581 typecheck_TRUE...the type is a subclass of CLS
582 typecheck_FALSE..the type is not a subclass of CLS
583 typecheck_MAYBE..check cannot be performed now because of unresolved
585 typecheck_FAIL...an exception has been thrown
587 *******************************************************************************/
589 static typecheck_result
590 merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
594 classref_or_classinfo *mlist;
596 TYPEINFO_ASSERT(cls);
598 /* primitive types aren't subclasses of anything. */
600 return typecheck_FALSE;
602 /* the null type can be cast to any reference type. */
603 if (typeclass == pseudo_class_Null)
604 return typecheck_TRUE;
606 TYPEINFO_ASSERT(typeclass->state & CLASS_LOADED);
607 TYPEINFO_ASSERT(typeclass->state & CLASS_LINKED);
609 /* check if the common typeclass is a subclass of CLS. */
610 if (class_issubclass(typeclass,cls))
611 return typecheck_TRUE;
613 /* check the mergedlist */
615 return typecheck_FALSE;
616 /* If all classinfos in the (non-empty) merged list are subclasses
617 * of CLS, return true, otherwise false.
618 * If there is at least one unresolved type in the list,
619 * return typecheck_MAYBE.
621 mlist = merged->list;
624 if (IS_CLASSREF(*mlist)) {
625 return typecheck_MAYBE;
627 if (!(mlist->cls->state & CLASS_LINKED))
628 if (!link_class(mlist->cls))
629 return typecheck_FAIL;
630 if (!class_issubclass(mlist->cls,cls))
631 return typecheck_FALSE;
634 return typecheck_TRUE;
637 /* typeinfo_is_assignable_to_class *********************************************
639 Check if a type is assignable to a given class type.
642 value............the type of the value
643 dest.............the type of the destination
646 typecheck_TRUE...the type is assignable
647 typecheck_FALSE..the type is not assignable
648 typecheck_MAYBE..check cannot be performed now because of unresolved
650 typecheck_FAIL...an exception has been thrown
652 *******************************************************************************/
655 typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
657 classref_or_classinfo c;
661 TYPEINFO_ASSERT(value);
663 c = value->typeclass;
665 /* assignments of primitive values are not checked here. */
666 if (!c.any && !dest.any)
667 return typecheck_TRUE;
669 /* primitive and reference types are not assignment compatible. */
670 if (!c.any || !dest.any)
671 return typecheck_FALSE;
673 /* the null type can be assigned to any type */
674 if (TYPEINFO_IS_NULLTYPE(*value))
675 return typecheck_TRUE;
677 /* uninitialized objects are not assignable */
678 if (TYPEINFO_IS_NEWOBJECT(*value))
679 return typecheck_FALSE;
681 if (IS_CLASSREF(c)) {
682 /* The value type is an unresolved class reference. */
683 classname = c.ref->name;
686 classname = c.cls->name;
689 if (IS_CLASSREF(dest)) {
690 /* the destination type is an unresolved class reference */
691 /* In this case we cannot tell a lot about assignability. */
693 /* the common case of value and dest type having the same classname */
694 if (dest.ref->name == classname && !value->merged)
695 return typecheck_TRUE;
697 /* we cannot tell if value is assignable to dest, so we */
698 /* leave it up to the resolving code to check this */
699 return typecheck_MAYBE;
702 /* { we know that dest is a loaded class } */
704 if (IS_CLASSREF(c)) {
705 /* the value type is an unresolved class reference */
707 /* the common case of value and dest type having the same classname */
708 if (dest.cls->name == classname)
709 return typecheck_TRUE;
711 /* we cannot tell if value is assignable to dest, so we */
712 /* leave it up to the resolving code to check this */
713 return typecheck_MAYBE;
716 /* { we know that both c and dest are loaded classes } */
717 /* (c may still have a merged list containing unresolved classrefs!) */
719 TYPEINFO_ASSERT(!IS_CLASSREF(c));
720 TYPEINFO_ASSERT(!IS_CLASSREF(dest));
724 TYPEINFO_ASSERT(cls->state & CLASS_LOADED);
725 TYPEINFO_ASSERT(dest.cls->state & CLASS_LOADED);
727 /* maybe we need to link the classes */
728 if (!(cls->state & CLASS_LINKED))
729 if (!link_class(cls))
730 return typecheck_FAIL;
731 if (!(dest.cls->state & CLASS_LINKED))
732 if (!link_class(dest.cls))
733 return typecheck_FAIL;
735 /* { we know that both c and dest are linked classes } */
736 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
737 TYPEINFO_ASSERT(dest.cls->state & CLASS_LINKED);
739 if (dest.cls->flags & ACC_INTERFACE) {
740 /* We are assigning to an interface type. */
741 return merged_implements_interface(cls,value->merged,dest.cls);
744 if (CLASSINFO_IS_ARRAY(dest.cls)) {
745 arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
746 int dimension = arraydesc->dimension;
747 classinfo *elementclass = (arraydesc->elementvftbl)
748 ? arraydesc->elementvftbl->class : NULL;
750 /* We are assigning to an array type. */
751 if (!TYPEINFO_IS_ARRAY(*value))
752 return typecheck_FALSE;
754 /* {Both value and dest.cls are array types.} */
756 /* value must have at least the dimension of dest.cls. */
757 if (value->dimension < dimension)
758 return typecheck_FALSE;
760 if (value->dimension > dimension) {
761 /* value has higher dimension so we need to check
762 * if its component array can be assigned to the
763 * element type of dest.cls */
765 if (!elementclass) return typecheck_FALSE;
767 if (elementclass->flags & ACC_INTERFACE) {
768 /* We are assigning to an interface type. */
769 return classinfo_implements_interface(pseudo_class_Arraystub,
773 /* We are assigning to a class type. */
774 return class_issubclass(pseudo_class_Arraystub,elementclass);
777 /* {value and dest.cls have the same dimension} */
779 if (value->elementtype != arraydesc->elementtype)
780 return typecheck_FALSE;
782 if (value->elementclass.any) {
783 /* We are assigning an array of objects so we have to
784 * check if the elements are assignable.
787 if (elementclass->flags & ACC_INTERFACE) {
788 /* We are assigning to an interface type. */
790 return merged_implements_interface(value->elementclass.cls,
795 /* We are assigning to a class type. */
796 return merged_is_subclass(value->elementclass.cls,value->merged,elementclass);
799 return typecheck_TRUE;
802 /* {dest.cls is not an array} */
803 /* {dest.cls is a loaded class} */
805 /* If there are any unresolved references in the merged list, we cannot */
806 /* tell if the assignment will be ok. */
807 /* This can only happen when cls is java.lang.Object */
808 if (cls == class_java_lang_Object && value->merged) {
809 classref_or_classinfo *mlist = value->merged->list;
810 int i = value->merged->count;
812 if (IS_CLASSREF(*mlist++))
813 return typecheck_MAYBE;
816 /* We are assigning to a class type */
817 if (cls->flags & ACC_INTERFACE)
818 cls = class_java_lang_Object;
820 return merged_is_subclass(cls,value->merged,dest.cls);
823 /* typeinfo_is_assignable ******************************************************
825 Check if a type is assignable to a given type.
828 value............the type of the value
829 dest.............the type of the destination, must not be a merged type
832 typecheck_TRUE...the type is assignable
833 typecheck_FALSE..the type is not assignable
834 typecheck_MAYBE..check cannot be performed now because of unresolved
836 typecheck_FAIL...an exception has been thrown
838 *******************************************************************************/
841 typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
843 TYPEINFO_ASSERT(value);
844 TYPEINFO_ASSERT(dest);
845 TYPEINFO_ASSERT(dest->merged == NULL);
847 return typeinfo_is_assignable_to_class(value,dest->typeclass);
850 /**********************************************************************/
851 /* INITIALIZATION FUNCTIONS */
852 /* The following functions fill in uninitialized typeinfo structures. */
853 /**********************************************************************/
855 /* typeinfo_init_classinfo *****************************************************
857 Initialize a typeinfo to a resolved class.
860 c................the class
863 *info............is initialized
866 true.............success
867 false............an exception has been thrown
869 *******************************************************************************/
872 typeinfo_init_classinfo(typeinfo *info, classinfo *c)
874 if ((info->typeclass.cls = c)->vftbl->arraydesc) {
875 if (c->vftbl->arraydesc->elementvftbl)
876 info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->class;
878 info->elementclass.any = NULL;
879 info->dimension = c->vftbl->arraydesc->dimension;
880 info->elementtype = c->vftbl->arraydesc->elementtype;
883 info->elementclass.any = NULL;
885 info->elementtype = 0;
890 /* typeinfo_init_class *********************************************************
892 Initialize a typeinfo to a possibly unresolved class type.
895 c................the class type
898 *info............is initialized
901 true.............success
902 false............an exception has been thrown
904 *******************************************************************************/
907 typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
913 TYPEINFO_ASSERT(c.any);
914 TYPEINFO_ASSERT(info);
916 /* if necessary, try to resolve lazily */
917 if (!resolve_classref_or_classinfo(NULL /* XXX should know method */,
918 c,resolveLazy,false,true,&cls))
924 typeinfo_init_classinfo(info,cls);
928 /* {the type could no be resolved lazily} */
930 info->typeclass.ref = c.ref;
931 info->elementclass.any = NULL;
935 /* handle array type references */
936 utf_ptr = c.ref->name->text;
937 len = c.ref->name->blength;
938 if (*utf_ptr == '[') {
939 /* count dimensions */
940 while (*utf_ptr == '[') {
945 if (*utf_ptr == 'L') {
948 info->elementtype = ARRAYTYPE_OBJECT;
949 info->elementclass.ref = class_get_classref(c.ref->referer,utf_new(utf_ptr,len));
952 /* an array with primitive element type */
953 /* should have been resolved above */
954 TYPEINFO_ASSERT(false);
960 /* typeinfo_init_from_typedesc *************************************************
962 Initialize a typeinfo from a typedesc.
965 desc.............the typedesc
968 *type............set to the TYPE_* constant of DESC (if type != NULL)
969 *info............receives the typeinfo (if info != NULL)
972 true.............success
973 false............an exception has been thrown
975 *******************************************************************************/
978 typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
980 TYPEINFO_ASSERT(desc);
982 #ifdef TYPEINFO_VERBOSE
983 fprintf(stderr,"typeinfo_init_from_typedesc(");
984 descriptor_debug_print_typedesc(stderr,desc);
985 fprintf(stderr,")\n");
992 if (desc->type == TYPE_ADR) {
993 TYPEINFO_ASSERT(desc->classref);
994 if (!typeinfo_init_class(info,CLASSREF_OR_CLASSINFO(desc->classref)))
998 TYPEINFO_INIT_PRIMITIVE(*info);
1004 /* typeinfos_init_from_methoddesc **********************************************
1006 Initialize an array of typeinfos and u1 TYPE_* values from a methoddesc.
1009 desc.............the methoddesc
1010 buflen...........number of parameters the buffer can hold
1011 twoword..........if true, use two parameter slots for two-word types
1014 *typebuf.........receives a TYPE_* constant for each parameter
1015 typebuf must be != NULL
1016 *infobuf.........receives a typeinfo for each parameter
1017 infobuf must be != NULL
1018 *returntype......receives a TYPE_* constant for the return type
1019 returntype may be NULL
1020 *returntypeinfo..receives a typeinfo for the return type
1021 returntypeinfo may be NULL
1024 true.............success
1025 false............an exception has been thrown
1028 If (according to BUFLEN) the buffers are to small to hold the
1029 parameter types, an internal error is thrown. This must be
1030 avoided by checking the number of parameters and allocating enough
1031 space before calling this function.
1033 *******************************************************************************/
1036 typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
1037 int buflen,bool twoword,
1038 u1 *returntype,typeinfo *returntypeinfo)
1043 TYPEINFO_ASSERT(desc);
1044 TYPEINFO_ASSERT(typebuf);
1045 TYPEINFO_ASSERT(infobuf);
1047 #ifdef TYPEINFO_VERBOSE
1048 fprintf(stderr,"typeinfos_init_from_methoddesc(");
1049 descriptor_debug_print_methoddesc(stderr,desc);
1050 fprintf(stderr,")\n");
1053 /* check arguments */
1054 for (i=0; i<desc->paramcount; ++i) {
1055 if (++args > buflen) {
1056 exceptions_throw_internalerror("Buffer too small for method arguments.");
1060 if (!typeinfo_init_from_typedesc(desc->paramtypes + i,typebuf++,infobuf++))
1063 if (twoword && (typebuf[-1] == TYPE_LNG || typebuf[-1] == TYPE_DBL)) {
1064 if (++args > buflen) {
1065 exceptions_throw_internalerror("Buffer too small for method arguments.");
1069 *typebuf++ = TYPE_VOID;
1070 TYPEINFO_INIT_PRIMITIVE(*infobuf);
1075 /* check returntype */
1077 if (!typeinfo_init_from_typedesc(&(desc->returntype),returntype,returntypeinfo))
1084 /* typedescriptor_init_from_typedesc *******************************************
1086 Initialize a typedescriptor from a typedesc.
1089 desc.............the typedesc
1092 *td..............receives the typedescriptor
1096 true.............success
1097 false............an exception has been thrown
1099 *******************************************************************************/
1102 typedescriptor_init_from_typedesc(typedescriptor *td,
1105 TYPEINFO_ASSERT(td);
1106 TYPEINFO_ASSERT(desc);
1108 td->type = desc->type;
1109 if (td->type == TYPE_ADR) {
1110 if (!typeinfo_init_class(&(td->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
1114 TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
1119 /* typeinfo_init_varinfo_from_typedesc *****************************************
1121 Initialize a varinfo from a typedesc.
1124 desc.............the typedesc
1127 *var.............receives the type
1131 true.............success
1132 false............an exception has been thrown
1134 *******************************************************************************/
1137 typeinfo_init_varinfo_from_typedesc(varinfo *var,
1140 TYPEINFO_ASSERT(var);
1141 TYPEINFO_ASSERT(desc);
1143 var->type = desc->type;
1144 if (var->type == TYPE_ADR) {
1145 if (!typeinfo_init_class(&(var->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
1149 TYPEINFO_INIT_PRIMITIVE(var->typeinfo);
1154 /* typeinfo_init_varinfos_from_methoddesc **************************************
1156 Initialize an array of varinfos from a methoddesc.
1159 desc.............the methoddesc
1160 buflen...........number of parameters the buffer can hold
1161 startindex.......the zero-based index of the first parameter to
1162 write to the array. In other words the number of
1163 parameters to skip at the beginning of the methoddesc.
1164 map..............map from parameter indices to varinfo indices
1165 (indexed like jitdata.local_map)
1168 *vars............array receiving the varinfos
1169 td[0] receives the type of the
1170 (startindex+1)th parameter of the method
1171 *returntype......receives the typedescriptor of the return type.
1172 returntype may be NULL
1175 true.............everything ok
1176 false............an exception has been thrown
1179 If (according to BUFLEN) the buffer is to small to hold the
1180 parameter types, an internal error is thrown. This must be
1181 avoided by checking the number of parameters and allocating enough
1182 space before calling this function.
1184 *******************************************************************************/
1187 typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
1189 int buflen, int startindex,
1191 typedescriptor *returntype)
1198 /* skip arguments */
1199 for (i=0; i<startindex; ++i) {
1201 if (IS_2_WORD_TYPE(desc->paramtypes[i].type))
1205 /* check arguments */
1206 for (i=startindex; i<desc->paramcount; ++i) {
1207 type = desc->paramtypes[i].type;
1208 varindex = map[5*slot + type];
1211 if (IS_2_WORD_TYPE(type))
1214 if (varindex == UNUSED)
1217 if (varindex >= buflen) {
1218 exceptions_throw_internalerror("Buffer too small for method arguments.");
1222 if (!typeinfo_init_varinfo_from_typedesc(vars + varindex, desc->paramtypes + i))
1226 /* check returntype */
1228 if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1235 /* typedescriptors_init_from_methoddesc ****************************************
1237 Initialize an array of typedescriptors from a methoddesc.
1240 desc.............the methoddesc
1241 buflen...........number of parameters the buffer can hold
1242 twoword..........if true, use two parameter slots for two-word types
1243 startindex.......the zero-based index of the first parameter to
1244 write to the array. In other words the number of
1245 parameters to skip at the beginning of the methoddesc.
1248 *td..............array receiving the typedescriptors.
1249 td[0] receives the typedescriptor of the
1250 (startindex+1)th parameter of the method
1251 *returntype......receives the typedescriptor of the return type.
1252 returntype may be NULL
1255 >= 0.............number of typedescriptors filled in TD
1256 -1...............an exception has been thrown
1259 If (according to BUFLEN) the buffer is to small to hold the
1260 parameter types, an internal error is thrown. This must be
1261 avoided by checking the number of parameters and allocating enough
1262 space before calling this function.
1264 *******************************************************************************/
1267 typedescriptors_init_from_methoddesc(typedescriptor *td,
1269 int buflen,bool twoword,int startindex,
1270 typedescriptor *returntype)
1275 /* check arguments */
1276 for (i=startindex; i<desc->paramcount; ++i) {
1277 if (++args > buflen) {
1278 exceptions_throw_internalerror("Buffer too small for method arguments.");
1282 if (!typedescriptor_init_from_typedesc(td,desc->paramtypes + i))
1286 if (twoword && (td[-1].type == TYPE_LNG || td[-1].type == TYPE_DBL)) {
1287 if (++args > buflen) {
1288 exceptions_throw_internalerror("Buffer too small for method arguments.");
1292 td->type = TYPE_VOID;
1293 TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
1298 /* check returntype */
1300 if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1307 /* typeinfo_init_component *****************************************************
1309 Initialize a typeinfo with the component type of a given array type.
1312 srcarray.........the typeinfo of the array type
1315 *dst.............receives the typeinfo of the component type
1318 true.............success
1319 false............an exception has been thrown
1321 *******************************************************************************/
1324 typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
1326 typeinfo_mergedlist *merged;
1328 TYPEINFO_ASSERT(srcarray);
1329 TYPEINFO_ASSERT(dst);
1331 if (TYPEINFO_IS_NULLTYPE(*srcarray)) {
1332 TYPEINFO_INIT_NULLTYPE(*dst);
1336 if (!TYPEINFO_IS_ARRAY(*srcarray)) {
1337 /* XXX should we make that a verify error? */
1338 exceptions_throw_internalerror("Trying to access component of non-array");
1342 /* save the mergedlist (maybe dst == srcarray) */
1344 merged = srcarray->merged;
1346 if (IS_CLASSREF(srcarray->typeclass)) {
1347 constant_classref *comp;
1348 comp = class_get_classref_component_of(srcarray->typeclass.ref);
1351 if (!typeinfo_init_class(dst,CLASSREF_OR_CLASSINFO(comp)))
1355 TYPEINFO_INIT_PRIMITIVE(*dst);
1361 if (!(srcarray->typeclass.cls->state & CLASS_LINKED)) {
1362 if (!link_class(srcarray->typeclass.cls)) {
1367 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl);
1368 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl->arraydesc);
1370 comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
1372 typeinfo_init_classinfo(dst,comp->class);
1374 TYPEINFO_INIT_PRIMITIVE(*dst);
1377 dst->merged = merged; /* XXX should we do a deep copy? */
1381 /* typeinfo_clone **************************************************************
1383 Create a deep copy of a typeinfo struct.
1386 src..............the typeinfo to copy
1389 *dest............receives the copy
1392 If src == dest this function is a nop.
1394 *******************************************************************************/
1397 typeinfo_clone(typeinfo *src,typeinfo *dest)
1400 classref_or_classinfo *srclist,*destlist;
1408 count = src->merged->count;
1409 TYPEINFO_ALLOCMERGED(dest->merged,count);
1410 dest->merged->count = count;
1412 srclist = src->merged->list;
1413 destlist = dest->merged->list;
1415 *destlist++ = *srclist++;
1419 /**********************************************************************/
1420 /* MISCELLANEOUS FUNCTIONS */
1421 /**********************************************************************/
1423 /* typeinfo_free ***************************************************************
1425 Free memory referenced by the given typeinfo. The typeinfo itself is not
1429 info.............the typeinfo
1431 *******************************************************************************/
1434 typeinfo_free(typeinfo *info)
1436 TYPEINFO_FREEMERGED_IF_ANY(info->merged);
1437 info->merged = NULL;
1440 /**********************************************************************/
1441 /* MERGING FUNCTIONS */
1442 /* The following functions are used to merge the types represented by */
1443 /* two typeinfo structures into one typeinfo structure. */
1444 /**********************************************************************/
1448 typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
1449 #ifdef TYPEINFO_VERBOSE
1450 fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
1451 fprintf(stderr,"Typeinfo x:\n");
1452 typeinfo_print(stderr,x,1);
1453 fprintf(stderr,"Typeinfo y:\n");
1454 typeinfo_print(stderr,y,1);
1458 exceptions_throw_verifyerror(m, str);
1461 /* Condition: clsx != clsy. */
1462 /* Returns: true if dest was changed (currently always true). */
1465 typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
1467 TYPEINFO_ASSERT(dest);
1468 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1469 TYPEINFO_ALLOCMERGED(dest->merged,2);
1470 dest->merged->count = 2;
1472 TYPEINFO_ASSERT(clsx.any != clsy.any);
1474 if (clsx.any < clsy.any) {
1475 dest->merged->list[0] = clsx;
1476 dest->merged->list[1] = clsy;
1479 dest->merged->list[0] = clsy;
1480 dest->merged->list[1] = clsx;
1486 /* Returns: true if dest was changed. */
1489 typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo cls)
1492 typeinfo_mergedlist *newmerged;
1493 classref_or_classinfo *mlist,*newlist;
1498 /* Check if cls is already in the mergedlist m. */
1500 if ((mlist++)->any == cls.any) { /* XXX check equal classrefs? */
1501 /* cls is in the list, so m is the resulting mergedlist */
1502 if (dest->merged == m)
1505 /* We have to copy the mergedlist */
1506 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1508 TYPEINFO_ALLOCMERGED(dest->merged,count);
1509 dest->merged->count = count;
1510 newlist = dest->merged->list;
1513 *newlist++ = *mlist++;
1519 /* Add cls to the mergedlist. */
1521 TYPEINFO_ALLOCMERGED(newmerged,count+1);
1522 newmerged->count = count+1;
1523 newlist = newmerged->list;
1526 if (mlist->any > cls.any)
1528 *newlist++ = *mlist++;
1533 *newlist++ = *mlist++;
1536 /* Put the new mergedlist into dest. */
1537 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1538 dest->merged = newmerged;
1543 /* Returns: true if dest was changed. */
1546 typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
1547 typeinfo_mergedlist *y)
1551 typeinfo_mergedlist *temp,*result;
1552 classref_or_classinfo *clsx,*clsy,*newlist;
1554 /* count the elements that will be in the resulting list */
1555 /* (Both lists are sorted, equal elements are counted only once.) */
1560 while (countx && county) {
1561 if (clsx->any == clsy->any) {
1567 else if (clsx->any < clsy->any) {
1577 count += countx + county;
1579 /* {The new mergedlist will have count entries.} */
1581 if ((x->count != count) && (y->count == count)) {
1582 temp = x; x = y; y = temp;
1584 /* {If one of x,y is already the result it is x.} */
1585 if (x->count == count) {
1586 /* x->merged is equal to the result */
1587 if (x == dest->merged)
1590 if (!dest->merged || dest->merged->count != count) {
1591 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1592 TYPEINFO_ALLOCMERGED(dest->merged,count);
1593 dest->merged->count = count;
1596 newlist = dest->merged->list;
1599 *newlist++ = *clsx++;
1604 /* {We have to merge two lists.} */
1606 /* allocate the result list */
1607 TYPEINFO_ALLOCMERGED(result,count);
1608 result->count = count;
1609 newlist = result->list;
1611 /* merge the sorted lists */
1616 while (countx && county) {
1617 if (clsx->any == clsy->any) {
1618 *newlist++ = *clsx++;
1623 else if (clsx->any < clsy->any) {
1624 *newlist++ = *clsx++;
1628 *newlist++ = *clsy++;
1633 *newlist++ = *clsx++;
1635 *newlist++ = *clsy++;
1637 /* replace the list in dest with the result list */
1638 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1639 dest->merged = result;
1644 /* typeinfo_merge_nonarrays ****************************************************
1646 Merge two non-array types.
1649 x................the first type
1650 y................the second type
1651 mergedx..........merged list of the first type, may be NULL
1652 mergedy..........merged list of the descond type, may be NULL
1655 *dest............receives the resulting merged list
1656 *result..........receives the resulting type
1659 typecheck_TRUE...*dest has been modified
1660 typecheck_FALSE..*dest has not been modified
1661 typecheck_FAIL...an exception has been thrown
1664 RESULT is an extra parameter so it can point to dest->typeclass or to
1667 *******************************************************************************/
1669 static typecheck_result
1670 typeinfo_merge_nonarrays(typeinfo *dest,
1671 classref_or_classinfo *result,
1672 classref_or_classinfo x,classref_or_classinfo y,
1673 typeinfo_mergedlist *mergedx,
1674 typeinfo_mergedlist *mergedy)
1676 classref_or_classinfo t;
1677 classinfo *tcls,*common;
1678 typeinfo_mergedlist *tmerged;
1684 TYPEINFO_ASSERT(dest && result && x.any && y.any);
1685 TYPEINFO_ASSERT(x.cls != pseudo_class_Null);
1686 TYPEINFO_ASSERT(y.cls != pseudo_class_Null);
1687 TYPEINFO_ASSERT(x.cls != pseudo_class_New);
1688 TYPEINFO_ASSERT(y.cls != pseudo_class_New);
1690 /*--------------------------------------------------*/
1692 /*--------------------------------------------------*/
1694 /* Common case 1: x and y are the same class or class reference */
1695 /* (This case is very simple unless *both* x and y really represent
1696 * merges of subclasses of clsx==clsy.)
1698 if ( (x.any == y.any) && (!mergedx || !mergedy) ) {
1700 /* DEBUG */ /* log_text("return simple x"); */
1701 changed = (dest->merged != NULL);
1702 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1703 dest->merged = NULL;
1705 /* DEBUG */ /* log_text("returning"); */
1709 xname = (IS_CLASSREF(x)) ? x.ref->name : x.cls->name;
1710 yname = (IS_CLASSREF(y)) ? y.ref->name : y.cls->name;
1712 /* Common case 2: xname == yname, at least one unresolved */
1713 if ((IS_CLASSREF(x) || IS_CLASSREF(y)) && (xname == yname))
1715 /* use the loaded one if any */
1716 if (!IS_CLASSREF(y))
1718 goto return_simple_x;
1721 /*--------------------------------------------------*/
1722 /* non-trivial cases */
1723 /*--------------------------------------------------*/
1725 #ifdef TYPEINFO_VERBOSE
1728 fprintf(stderr,"merge_nonarrays:\n");
1729 fprintf(stderr," ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,xname);fprintf(stderr,"\n");
1730 fprintf(stderr," ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,yname);fprintf(stderr,"\n");
1732 typeinfo_init_class(&dbgx,x);
1733 dbgx.merged = mergedx;
1734 typeinfo_init_class(&dbgy,y);
1735 dbgy.merged = mergedy;
1736 typeinfo_print(stderr,&dbgx,4);
1737 fprintf(stderr," with:\n");
1738 typeinfo_print(stderr,&dbgy,4);
1742 TYPEINFO_ASSERT(IS_CLASSREF(x) || (x.cls->state & CLASS_LOADED));
1743 TYPEINFO_ASSERT(IS_CLASSREF(y) || (y.cls->state & CLASS_LOADED));
1745 /* If y is unresolved or an interface, swap x and y. */
1746 if (IS_CLASSREF(y) || (!IS_CLASSREF(x) && y.cls->flags & ACC_INTERFACE))
1748 t = x; x = y; y = t;
1749 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1752 /* {We know: If only one of x,y is unresolved it is x,} */
1753 /* { If both x,y are resolved and only one of x,y is an interface it is x.} */
1755 if (IS_CLASSREF(x)) {
1756 /* {We know: x and y have different class names} */
1758 /* Check if we are merging an unresolved type with java.lang.Object */
1759 if (y.cls == class_java_lang_Object && !mergedy) {
1761 goto return_simple_x;
1764 common = class_java_lang_Object;
1765 goto merge_with_simple_x;
1768 /* {We know: both x and y are resolved} */
1769 /* {We know: If only one of x,y is an interface it is x.} */
1771 TYPEINFO_ASSERT(!IS_CLASSREF(x) && !IS_CLASSREF(y));
1772 TYPEINFO_ASSERT(x.cls->state & CLASS_LOADED);
1773 TYPEINFO_ASSERT(y.cls->state & CLASS_LOADED);
1775 /* Handle merging of interfaces: */
1776 if (x.cls->flags & ACC_INTERFACE) {
1777 /* {x.cls is an interface and mergedx == NULL.} */
1779 if (y.cls->flags & ACC_INTERFACE) {
1780 /* We are merging two interfaces. */
1781 /* {mergedy == NULL} */
1783 /* {We know that x.cls!=y.cls (see common case at beginning.)} */
1784 result->cls = class_java_lang_Object;
1785 return typeinfo_merge_two(dest,x,y);
1788 /* {We know: x is an interface, y is a class.} */
1790 /* Check if we are merging an interface with java.lang.Object */
1791 if (y.cls == class_java_lang_Object && !mergedy) {
1793 goto return_simple_x;
1796 /* If the type y implements x then the result of the merge
1797 * is x regardless of mergedy.
1800 /* we may have to link the classes */
1801 if (!(x.cls->state & CLASS_LINKED))
1802 if (!link_class(x.cls))
1803 return typecheck_FAIL;
1804 if (!(y.cls->state & CLASS_LINKED))
1805 if (!link_class(y.cls))
1806 return typecheck_FAIL;
1808 TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
1809 TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
1811 if (CLASSINFO_IMPLEMENTS_INTERFACE(y.cls,x.cls->index))
1813 /* y implements x, so the result of the merge is x. */
1814 goto return_simple_x;
1817 r = mergedlist_implements_interface(mergedy,x.cls);
1818 if (r == typecheck_FAIL)
1820 if (r == typecheck_TRUE)
1822 /* y implements x, so the result of the merge is x. */
1823 goto return_simple_x;
1826 /* {We know: x is an interface, the type y a class or a merge
1827 * of subclasses and is not guaranteed to implement x.} */
1829 common = class_java_lang_Object;
1830 goto merge_with_simple_x;
1833 /* {We know: x and y are classes (not interfaces).} */
1835 /* we may have to link the classes */
1836 if (!(x.cls->state & CLASS_LINKED))
1837 if (!link_class(x.cls))
1838 return typecheck_FAIL;
1839 if (!(y.cls->state & CLASS_LINKED))
1840 if (!link_class(y.cls))
1841 return typecheck_FAIL;
1843 TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
1844 TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
1846 /* If *x is deeper in the inheritance hierarchy swap x and y. */
1847 if (x.cls->index > y.cls->index) {
1848 t = x; x = y; y = t;
1849 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1852 /* {We know: y is at least as deep in the hierarchy as x.} */
1854 /* Find nearest common anchestor for the classes. */
1859 while (tcls->index > common->index)
1862 while (common != tcls) {
1863 common = common->super;
1867 /* {common == nearest common anchestor of x and y.} */
1869 /* If x.cls==common and x is a whole class (not a merge of subclasses)
1870 * then the result of the merge is x.
1872 if (x.cls == common && !mergedx) {
1873 goto return_simple_x;
1877 result->cls = common;
1879 return typeinfo_merge_mergedlists(dest,mergedx,mergedy);
1881 return typeinfo_merge_add(dest,mergedx,y);
1884 merge_with_simple_x:
1885 result->cls = common;
1887 return typeinfo_merge_add(dest,mergedy,x);
1889 return typeinfo_merge_two(dest,x,y);
1892 /* typeinfo_merge **************************************************************
1897 m................method for exception messages
1898 dest.............the first type
1899 y................the second type
1902 *dest............receives the result of the merge
1905 typecheck_TRUE...*dest has been modified
1906 typecheck_FALSE..*dest has not been modified
1907 typecheck_FAIL...an exception has been thrown
1910 1) *dest must be a valid initialized typeinfo
1913 *******************************************************************************/
1916 typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y)
1920 classref_or_classinfo common;
1921 classref_or_classinfo elementclass;
1927 /*--------------------------------------------------*/
1929 /*--------------------------------------------------*/
1931 /* Merging something with itself is a nop */
1933 return typecheck_FALSE;
1935 /* Merging two returnAddress types is ok. */
1936 /* Merging two different returnAddresses never happens, as the verifier */
1937 /* keeps them separate in order to check all the possible return paths */
1938 /* from JSR subroutines. */
1939 if (!dest->typeclass.any && !y->typeclass.any) {
1940 TYPEINFO_ASSERT(TYPEINFO_RETURNADDRESS(*dest) == TYPEINFO_RETURNADDRESS(*y));
1941 return typecheck_FALSE;
1944 /* Primitive types cannot be merged with reference types */
1945 /* This must be checked before calls to typeinfo_merge. */
1946 TYPEINFO_ASSERT(dest->typeclass.any && y->typeclass.any);
1948 /* handle uninitialized object types */
1949 if (TYPEINFO_IS_NEWOBJECT(*dest) || TYPEINFO_IS_NEWOBJECT(*y)) {
1950 if (!TYPEINFO_IS_NEWOBJECT(*dest) || !TYPEINFO_IS_NEWOBJECT(*y)) {
1951 typeinfo_merge_error(m,"Trying to merge uninitialized object type.",dest,y);
1952 return typecheck_FAIL;
1954 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*dest) != TYPEINFO_NEWOBJECT_INSTRUCTION(*y)) {
1955 typeinfo_merge_error(m,"Trying to merge different uninitialized objects.",dest,y);
1956 return typecheck_FAIL;
1958 /* the same uninitialized object -- no change */
1959 return typecheck_FALSE;
1962 /*--------------------------------------------------*/
1964 /*--------------------------------------------------*/
1966 /* Common case: dest and y are the same class or class reference */
1967 /* (This case is very simple unless *both* dest and y really represent
1968 * merges of subclasses of class dest==class y.)
1970 if ((dest->typeclass.any == y->typeclass.any) && (!dest->merged || !y->merged)) {
1972 changed = (dest->merged != NULL);
1973 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1974 dest->merged = NULL;
1978 /* Handle null types: */
1979 if (TYPEINFO_IS_NULLTYPE(*y)) {
1980 return typecheck_FALSE;
1982 if (TYPEINFO_IS_NULLTYPE(*dest)) {
1983 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1984 TYPEINFO_CLONE(*y,*dest);
1985 return typecheck_TRUE;
1988 /* Common case: two types with the same name, at least one unresolved */
1989 if (IS_CLASSREF(dest->typeclass)) {
1990 if (IS_CLASSREF(y->typeclass)) {
1991 if (dest->typeclass.ref->name == y->typeclass.ref->name)
1995 /* XXX should we take y instead of dest here? */
1996 if (dest->typeclass.ref->name == y->typeclass.cls->name)
2001 if (IS_CLASSREF(y->typeclass)
2002 && (dest->typeclass.cls->name == y->typeclass.ref->name))
2008 /*--------------------------------------------------*/
2009 /* non-trivial cases */
2010 /*--------------------------------------------------*/
2012 #ifdef TYPEINFO_VERBOSE
2013 fprintf(stderr,"merge:\n");
2014 typeinfo_print(stderr,dest,4);
2015 typeinfo_print(stderr,y,4);
2018 /* This function uses x internally, so x and y can be swapped
2019 * without changing dest. */
2023 /* Handle merging of arrays: */
2024 if (TYPEINFO_IS_ARRAY(*x) && TYPEINFO_IS_ARRAY(*y)) {
2026 /* Make x the one with lesser dimension */
2027 if (x->dimension > y->dimension) {
2028 tmp = x; x = y; y = tmp;
2031 /* If one array (y) has higher dimension than the other,
2032 * interpret it as an array (same dim. as x) of Arraystubs. */
2033 if (x->dimension < y->dimension) {
2034 dimension = x->dimension;
2035 elementtype = ARRAYTYPE_OBJECT;
2036 elementclass.cls = pseudo_class_Arraystub;
2039 dimension = y->dimension;
2040 elementtype = y->elementtype;
2041 elementclass = y->elementclass;
2044 /* {The arrays are of the same dimension.} */
2046 if (x->elementtype != elementtype) {
2047 /* Different element types are merged, so the resulting array
2048 * type has one accessible dimension less. */
2049 if (--dimension == 0) {
2050 common.cls = pseudo_class_Arraystub;
2052 elementclass.any = NULL;
2055 common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub,true);
2057 exceptions_throw_internalerror("XXX Coult not create array class");
2058 return typecheck_FAIL;
2061 elementtype = ARRAYTYPE_OBJECT;
2062 elementclass.cls = pseudo_class_Arraystub;
2066 /* {The arrays have the same dimension and elementtype.} */
2068 if (elementtype == ARRAYTYPE_OBJECT) {
2069 /* The elements are references, so their respective
2070 * types must be merged.
2072 r = typeinfo_merge_nonarrays(dest,
2076 x->merged,y->merged);
2077 TYPEINFO_ASSERT(r != typecheck_MAYBE);
2078 if (r == typecheck_FAIL)
2082 /* DEBUG */ /* log_text("finding resulting array class: "); */
2083 if (IS_CLASSREF(elementclass))
2084 common.ref = class_get_classref_multiarray_of(dimension,elementclass.ref);
2086 common.cls = class_multiarray_of(dimension,elementclass.cls,true);
2088 exceptions_throw_internalerror("XXX Coult not create array class");
2089 return typecheck_FAIL;
2092 /* DEBUG */ /* utf_display_printable_ascii(common->name); printf("\n"); */
2095 common.any = y->typeclass.any;
2100 /* {We know that at least one of x or y is no array, so the
2101 * result cannot be an array.} */
2103 r = typeinfo_merge_nonarrays(dest,
2105 x->typeclass,y->typeclass,
2106 x->merged,y->merged);
2107 TYPEINFO_ASSERT(r != typecheck_MAYBE);
2108 if (r == typecheck_FAIL)
2114 elementclass.any = NULL;
2117 /* Put the new values into dest if neccessary. */
2119 if (dest->typeclass.any != common.any) {
2120 dest->typeclass.any = common.any;
2123 if (dest->dimension != dimension) {
2124 dest->dimension = dimension;
2127 if (dest->elementtype != elementtype) {
2128 dest->elementtype = elementtype;
2131 if (dest->elementclass.any != elementclass.any) {
2132 dest->elementclass.any = elementclass.any;
2138 #endif /* ENABLE_VERIFER */
2141 /**********************************************************************/
2142 /* DEBUGGING HELPERS */
2143 /**********************************************************************/
2145 #ifdef TYPEINFO_DEBUG
2149 typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
2151 if (a->any == b->any) return 0;
2152 if (a->any < b->any) return -1;
2157 typeinfo_test_parse(typeinfo *info,char *str)
2164 utf *desc = utf_new_char(str);
2166 num = typeinfo_count_method_args(desc,false);
2168 typebuf = DMNEW(u1,num);
2169 infobuf = DMNEW(typeinfo,num);
2171 typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
2174 TYPEINFO_ALLOCMERGED(info->merged,num);
2175 info->merged->count = num;
2177 for (i=0; i<num; ++i) {
2178 if (typebuf[i] != TYPE_ADR) {
2179 log_text("non-reference type in mergedlist");
2183 info->merged->list[i].any = infobuf[i].typeclass.any;
2185 qsort(info->merged->list,num,sizeof(classref_or_classinfo),
2186 (int(*)(const void *,const void *))&typeinfo_test_compare);
2189 typeinfo_init_from_method_args(desc,NULL,NULL,0,false,
2195 #define TYPEINFO_TEST_BUFLEN 4000
2198 typeinfo_equal(typeinfo *x,typeinfo *y)
2202 if (x->typeclass.any != y->typeclass.any) return false;
2203 if (x->dimension != y->dimension) return false;
2205 if (x->elementclass.any != y->elementclass.any) return false;
2206 if (x->elementtype != y->elementtype) return false;
2209 if (TYPEINFO_IS_NEWOBJECT(*x))
2210 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*x)
2211 != TYPEINFO_NEWOBJECT_INSTRUCTION(*y))
2214 if (x->merged || y->merged) {
2215 if (!(x->merged && y->merged)) return false;
2216 if (x->merged->count != y->merged->count) return false;
2217 for (i=0; i<x->merged->count; ++i)
2218 if (x->merged->list[i].any != y->merged->list[i].any)
2225 typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
2228 bool changed,changed_should_be;
2231 TYPEINFO_CLONE(*a,dest);
2234 typeinfo_print_short(stdout,&dest);
2236 typeinfo_print_short(stdout,b);
2239 r = typeinfo_merge(NULL,&dest,b);
2240 if (r == typecheck_FAIL) {
2241 printf("EXCEPTION\n");
2244 changed = (r) ? 1 : 0;
2245 changed_should_be = (!typeinfo_equal(&dest,a)) ? 1 : 0;
2247 printf(" %s\n",(changed) ? "changed" : "=");
2249 if (typeinfo_equal(&dest,result)) {
2251 typeinfo_print_short(stdout,&dest);
2253 if (changed != changed_should_be) {
2254 printf("WRONG RETURN VALUE!\n");
2260 typeinfo_print_short(stdout,&dest);
2262 printf("SHOULD BE ");
2263 typeinfo_print_short(stdout,result);
2271 typeinfo_inc_dimension(typeinfo *info)
2273 if (info->dimension++ == 0) {
2274 info->elementtype = ARRAYTYPE_OBJECT;
2275 info->elementclass = info->typeclass;
2277 info->typeclass = class_array_of(info->typeclass,true);
2281 #define TYPEINFO_TEST_MAXDIM 10
2284 typeinfo_testrun(char *filename)
2286 char buf[TYPEINFO_TEST_BUFLEN];
2287 char bufa[TYPEINFO_TEST_BUFLEN];
2288 char bufb[TYPEINFO_TEST_BUFLEN];
2289 char bufc[TYPEINFO_TEST_BUFLEN];
2293 FILE *file = fopen(filename,"rt");
2297 log_text("could not open typeinfo test file");
2301 while (fgets(buf,TYPEINFO_TEST_BUFLEN,file)) {
2302 if (buf[0] == '#' || !strlen(buf))
2305 res = sscanf(buf,"%s\t%s\t%s\n",bufa,bufb,bufc);
2306 if (res != 3 || !strlen(bufa) || !strlen(bufb) || !strlen(bufc)) {
2307 log_text("Invalid line in typeinfo test file (none of empty, comment or test)");
2312 typeinfo_test_parse(&a,bufa);
2313 typeinfo_test_parse(&b,bufb);
2314 typeinfo_test_parse(&c,bufc);
2319 typeinfo_testmerge(&a,&b,&c,&failed); /* check result */
2320 typeinfo_testmerge(&b,&a,&c,&failed); /* check commutativity */
2322 if (TYPEINFO_IS_NULLTYPE(a)) break;
2323 if (TYPEINFO_IS_NULLTYPE(b)) break;
2324 if (TYPEINFO_IS_NULLTYPE(c)) break;
2326 maxdim = a.dimension;
2327 if (b.dimension > maxdim) maxdim = b.dimension;
2328 if (c.dimension > maxdim) maxdim = c.dimension;
2331 if (maxdim < TYPEINFO_TEST_MAXDIM) {
2332 typeinfo_inc_dimension(&a);
2333 typeinfo_inc_dimension(&b);
2334 typeinfo_inc_dimension(&c);
2336 } while (maxdim < TYPEINFO_TEST_MAXDIM);
2343 fprintf(stderr,"Failed typeinfo_merge tests: %d\n",failed);
2344 log_text("Failed test");
2352 log_text("Running typeinfo test file...");
2353 typeinfo_testrun("typeinfo.tst");
2354 log_text("Finished typeinfo test file.");
2359 typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc)
2361 typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
2365 #define TYPEINFO_MAXINDENT 80
2368 typeinfo_print_class(FILE *file,classref_or_classinfo c)
2370 /*fprintf(file,"<class %p>",c.any);*/
2373 fprintf(file,"<null>");
2376 if (IS_CLASSREF(c)) {
2377 fprintf(file,"<ref>");
2378 utf_fprint_printable_ascii(file,c.ref->name);
2381 utf_fprint_printable_ascii(file,c.cls->name);
2387 typeinfo_print(FILE *file,typeinfo *info,int indent)
2390 char ind[TYPEINFO_MAXINDENT + 1];
2394 if (indent > TYPEINFO_MAXINDENT) indent = TYPEINFO_MAXINDENT;
2396 for (i=0; i<indent; ++i)
2400 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2401 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2403 fprintf(file,"%sreturnAddress (L%03d)\n",ind,bptr->nr);
2405 fprintf(file,"%sprimitive\n",ind);
2409 if (TYPEINFO_IS_NULLTYPE(*info)) {
2410 fprintf(file,"%snull\n",ind);
2414 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2415 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2417 fprintf(file,"%sNEW(%p):",ind,(void*)ins);
2418 typeinfo_print_class(file,ins[-1].sx.val.c);
2422 fprintf(file,"%sNEW(this)",ind);
2427 fprintf(file,"%sClass: ",ind);
2428 typeinfo_print_class(file,info->typeclass);
2431 if (TYPEINFO_IS_ARRAY(*info)) {
2432 fprintf(file,"%sDimension: %d",ind,(int)info->dimension);
2433 fprintf(file,"\n%sElements: ",ind);
2434 switch (info->elementtype) {
2435 case ARRAYTYPE_INT : fprintf(file,"int\n"); break;
2436 case ARRAYTYPE_LONG : fprintf(file,"long\n"); break;
2437 case ARRAYTYPE_FLOAT : fprintf(file,"float\n"); break;
2438 case ARRAYTYPE_DOUBLE : fprintf(file,"double\n"); break;
2439 case ARRAYTYPE_BYTE : fprintf(file,"byte\n"); break;
2440 case ARRAYTYPE_CHAR : fprintf(file,"char\n"); break;
2441 case ARRAYTYPE_SHORT : fprintf(file,"short\n"); break;
2442 case ARRAYTYPE_BOOLEAN : fprintf(file,"boolean\n"); break;
2444 case ARRAYTYPE_OBJECT:
2445 typeinfo_print_class(file,info->elementclass);
2450 fprintf(file,"INVALID ARRAYTYPE!\n");
2455 fprintf(file,"%sMerged: ",ind);
2456 for (i=0; i<info->merged->count; ++i) {
2457 if (i) fprintf(file,", ");
2458 typeinfo_print_class(file,info->merged->list[i]);
2465 typeinfo_print_short(FILE *file,typeinfo *info)
2471 /*fprintf(file,"<typeinfo %p>",info);*/
2474 fprintf(file,"(typeinfo*)NULL");
2478 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2479 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2481 fprintf(file,"ret(L%03d)",bptr->nr);
2483 fprintf(file,"primitive");
2487 if (TYPEINFO_IS_NULLTYPE(*info)) {
2488 fprintf(file,"null");
2492 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2493 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2495 /*fprintf(file,"<ins %p>",ins);*/
2496 fprintf(file,"NEW(%p):",(void*)ins);
2497 typeinfo_print_class(file,ins[-1].sx.val.c);
2500 fprintf(file,"NEW(this)");
2504 typeinfo_print_class(file,info->typeclass);
2508 for (i=0; i<info->merged->count; ++i) {
2509 if (i) fprintf(file,",");
2510 typeinfo_print_class(file,info->merged->list[i]);
2517 typeinfo_print_type(FILE *file,int type,typeinfo *info)
2520 case TYPE_VOID: fprintf(file,"V"); break;
2521 case TYPE_INT: fprintf(file,"I"); break;
2522 case TYPE_FLT: fprintf(file,"F"); break;
2523 case TYPE_DBL: fprintf(file,"D"); break;
2524 case TYPE_LNG: fprintf(file,"J"); break;
2525 case TYPE_RET: fprintf(file,"R:"); /* FALLTHROUGH! */
2527 typeinfo_print_short(file,info);
2536 typedescriptor_print(FILE *file,typedescriptor *td)
2538 typeinfo_print_type(file,td->type,&(td->typeinfo));
2542 typevector_print(FILE *file,varinfo *vec,int size)
2546 for (i=0; i<size; ++i) {
2547 fprintf(file," %d=",i);
2548 typeinfo_print_type(file, vec[i].type, &(vec[i].typeinfo));
2552 #endif /* TYPEINFO_DEBUG */
2556 * These are local overrides for various environment variables in Emacs.
2557 * Please do not remove this and leave it at the end of the file, where
2558 * Emacs will automagically detect them.
2559 * ---------------------------------------------------------------------
2562 * indent-tabs-mode: t
2566 * vim:noexpandtab:sw=4:ts=4: