1 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 #include "mm/memory.h"
33 #include "toolbox/logging.h"
36 #include "vm/exceptions.h"
37 #include "vm/primitive.hpp"
38 #include "vm/resolve.h"
40 #include "vm/jit/jit.h"
41 #include "vm/jit/verify/typeinfo.h"
43 #include "vmcore/class.h"
44 #include "vmcore/descriptor.h"
45 #include "vmcore/loader.h"
48 /* check if a linked class is an array class. Only use for linked classes! */
49 #define CLASSINFO_IS_ARRAY(clsinfo) ((clsinfo)->vftbl->arraydesc != NULL)
51 /* check if a linked class implements the interface with the given index */
52 #define CLASSINFO_IMPLEMENTS_INTERFACE(cls,index) \
53 ( ((index) < (cls)->vftbl->interfacetablelength) \
54 && ( (cls)->vftbl->interfacetable[-(index)] != NULL ) )
56 /******************************************************************************/
58 /******************************************************************************/
61 #define TYPEINFO_ASSERT(cond) assert(cond)
63 #define TYPEINFO_ASSERT(cond)
66 /**********************************************************************/
67 /* TYPEVECTOR FUNCTIONS */
68 /**********************************************************************/
70 #if defined(ENABLE_VERIFIER)
72 /* typevector_copy *************************************************************
74 Return a copy of the given typevector.
77 src..............typevector set to copy, must be != NULL
78 size.............number of elements per typevector
81 a pointer to the new typevector set
83 *******************************************************************************/
86 typevector_copy(varinfo *src, int size)
92 dst = DNEW_TYPEVECTOR(size);
93 memcpy(dst,src,TYPEVECTOR_SIZE(size));
98 /* typevector_copy_inplace *****************************************************
100 Copy a typevector to a given destination.
103 src..............typevector to copy, must be != NULL
104 dst..............destination to write the copy to
105 size.............number of elements per typevector
107 *******************************************************************************/
110 typevector_copy_inplace(varinfo *src,varinfo *dst,int size)
112 memcpy(dst,src,TYPEVECTOR_SIZE(size));
115 /* typevector_checktype ********************************************************
117 Check if the typevector contains a given type at a given index.
120 vec..............typevector set, must be != NULL
121 index............index of component to check
122 type.............TYPE_* constant to check against
125 true if the typevector contains TYPE at INDEX,
128 *******************************************************************************/
131 typevector_checktype(varinfo *vec,int index,int type)
133 TYPEINFO_ASSERT(vec);
135 return vec[index].type == type;
138 /* typevector_checkreference ***************************************************
140 Check if the typevector contains a reference at a given index.
143 vec..............typevector, must be != NULL
144 index............index of component to check
147 true if the typevector contains a reference at INDEX,
150 *******************************************************************************/
153 typevector_checkreference(varinfo *vec, int index)
155 TYPEINFO_ASSERT(vec);
156 return TYPEDESC_IS_REFERENCE(vec[index]);
159 /* typevectorset_checkretaddr **************************************************
161 Check if the typevectors contains a returnAddress at a given index.
164 vec..............typevector, must be != NULL
165 index............index of component to check
168 true if the typevector contains a returnAddress at INDEX,
171 *******************************************************************************/
174 typevector_checkretaddr(varinfo *vec,int index)
176 TYPEINFO_ASSERT(vec);
177 return TYPEDESC_IS_RETURNADDRESS(vec[index]);
180 /* typevector_store ************************************************************
182 Store a type at a given index in the typevector.
185 vec..............typevector set, must be != NULL
186 index............index of component to set
187 type.............TYPE_* constant of type to set
188 info.............typeinfo of type to set, may be NULL,
191 *******************************************************************************/
194 typevector_store(varinfo *vec,int index,int type,typeinfo_t *info)
196 TYPEINFO_ASSERT(vec);
198 vec[index].type = type;
200 TYPEINFO_COPY(*info,vec[index].typeinfo);
203 /* typevector_store_retaddr ****************************************************
205 Store a returnAddress type at a given index in the typevector.
208 vec..............typevector set, must be != NULL
209 index............index of component to set
210 info.............typeinfo of the returnAddress.
212 *******************************************************************************/
215 typevector_store_retaddr(varinfo *vec,int index,typeinfo_t *info)
217 TYPEINFO_ASSERT(vec);
218 TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
220 vec[index].type = TYPE_ADR;
221 TYPEINFO_INIT_RETURNADDRESS(vec[index].typeinfo,
222 TYPEINFO_RETURNADDRESS(*info));
225 /* typevector_init_object ******************************************************
227 Replace all uninitialized object types in the typevector set which were
228 created by the given instruction by initialized object types.
231 set..............typevector set
232 ins..............instruction which created the uninitialized object type
233 initclass........class of the initialized object type to set
234 size.............number of elements per typevector
237 true.............success
238 false............an exception has been thrown
240 XXX maybe we should do the lazy resolving before calling this function
242 *******************************************************************************/
245 typevector_init_object(varinfo *set,void *ins,
246 classref_or_classinfo initclass,
251 for (i=0; i<size; ++i) {
252 if (set[i].type == TYPE_ADR
253 && TYPEINFO_IS_NEWOBJECT(set[i].typeinfo)
254 && TYPEINFO_NEWOBJECT_INSTRUCTION(set[i].typeinfo) == ins)
256 if (!typeinfo_init_class(&(set[i].typeinfo),initclass))
263 /* typevector_merge ************************************************************
265 Merge a typevector with another one.
266 The given typevectors must have the same number of components.
269 m................method for exception messages
270 dst..............the first typevector
271 y................the second typevector
272 size.............number of elements per typevector
275 *dst.............the resulting typevector
278 typecheck_TRUE...dst has been modified
279 typecheck_FALSE..dst has not been modified
280 typecheck_FAIL...an exception has been thrown
282 *******************************************************************************/
285 typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size)
287 bool changed = false;
293 if (a->type != TYPE_VOID && a->type != b->type) {
297 else if (a->type == TYPE_ADR) {
298 if (TYPEINFO_IS_PRIMITIVE(a->typeinfo)) {
299 /* 'a' is a returnAddress */
300 if (!TYPEINFO_IS_PRIMITIVE(b->typeinfo)
301 || (TYPEINFO_RETURNADDRESS(a->typeinfo)
302 != TYPEINFO_RETURNADDRESS(b->typeinfo)))
309 /* 'a' is a reference */
310 if (TYPEINFO_IS_PRIMITIVE(b->typeinfo)) {
315 /* two reference types are merged. There cannot be */
316 /* a merge error. In the worst case we get j.l.O. */
317 r = typeinfo_merge(m,&(a->typeinfo),&(b->typeinfo));
318 if (r == typecheck_FAIL)
330 /**********************************************************************/
331 /* READ-ONLY FUNCTIONS */
332 /* The following functions don't change typeinfo data. */
333 /**********************************************************************/
335 /* typeinfo_is_array ***********************************************************
337 Check whether a typeinfo describes an array type.
340 info.............the typeinfo, must be != NULL
343 true if INFO describes an array type.
345 *******************************************************************************/
348 typeinfo_is_array(typeinfo_t *info)
350 TYPEINFO_ASSERT(info);
351 return TYPEINFO_IS_ARRAY(*info);
354 /* typeinfo_is_primitive_array *************************************************
356 Check whether a typeinfo describes a primitive array type.
359 info.............the typeinfo, must be != NULL
362 true if INFO describes an array of a primitive type.
364 *******************************************************************************/
367 typeinfo_is_primitive_array(typeinfo_t *info,int arraytype)
369 TYPEINFO_ASSERT(info);
370 return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
373 /* typeinfo_is_array_of_refs ***************************************************
375 Check whether a typeinfo describes an array of references type.
378 info.............the typeinfo, must be != NULL
381 true if INFO describes an array of a refrence type.
383 *******************************************************************************/
386 typeinfo_is_array_of_refs(typeinfo_t *info)
388 TYPEINFO_ASSERT(info);
389 return TYPEINFO_IS_ARRAY_OF_REFS(*info);
392 /* interface_extends_interface *************************************************
394 Check if a resolved interface extends a given resolved interface.
397 cls..............the interface, must be linked
398 interf...........the interface to check against
401 true.............CLS extends INTERF
402 false............CLS does not extend INTERF
404 *******************************************************************************/
407 interface_extends_interface(classinfo *cls,classinfo *interf)
411 TYPEINFO_ASSERT(cls);
412 TYPEINFO_ASSERT(interf);
413 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
414 TYPEINFO_ASSERT((cls->flags & ACC_INTERFACE) != 0);
415 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
417 /* first check direct superinterfaces */
418 for (i=0; i<cls->interfacescount; ++i) {
419 if (cls->interfaces[i] == interf)
423 /* check indirect superinterfaces */
424 for (i=0; i<cls->interfacescount; ++i) {
425 if (interface_extends_interface(cls->interfaces[i],interf))
432 /* classinfo_implements_interface **********************************************
434 Check if a resolved class implements a given resolved interface.
437 cls..............the class
438 interf...........the interface
441 typecheck_TRUE...CLS implements INTERF
442 typecheck_FALSE..CLS does not implement INTERF
443 typecheck_FAIL...an exception has been thrown
445 *******************************************************************************/
447 static typecheck_result
448 classinfo_implements_interface(classinfo *cls,classinfo *interf)
450 TYPEINFO_ASSERT(cls);
451 TYPEINFO_ASSERT(interf);
452 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
454 if (!(cls->state & CLASS_LINKED))
455 if (!link_class(cls))
456 return typecheck_FAIL;
458 if (cls->flags & ACC_INTERFACE) {
459 /* cls is an interface */
461 return typecheck_TRUE;
463 /* check superinterfaces */
464 return interface_extends_interface(cls,interf);
467 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
468 return CLASSINFO_IMPLEMENTS_INTERFACE(cls,interf->index);
471 /* mergedlist_implements_interface *********************************************
473 Check if all the classes in a given merged list implement a given resolved
477 merged...........the list of merged class types
478 interf...........the interface to check against
481 typecheck_TRUE...all classes implement INTERF
482 typecheck_FALSE..there is at least one class that does not implement
484 typecheck_MAYBE..check cannot be performed now because of unresolved
486 typecheck_FAIL...an exception has been thrown
488 *******************************************************************************/
490 static typecheck_result
491 mergedlist_implements_interface(typeinfo_mergedlist_t *merged,
495 classref_or_classinfo *mlist;
498 TYPEINFO_ASSERT(interf);
499 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
501 /* Check if there is an non-empty mergedlist. */
503 return typecheck_FALSE;
505 /* If all classinfos in the (non-empty) merged array implement the
506 * interface return true, otherwise false.
508 mlist = merged->list;
511 if (IS_CLASSREF(*mlist)) {
512 return typecheck_MAYBE;
514 r = classinfo_implements_interface((mlist++)->cls,interf);
515 if (r != typecheck_TRUE)
518 return typecheck_TRUE;
521 /* merged_implements_interface *************************************************
523 Check if a possible merged type implements a given resolved interface
527 typeclass........(common) class of the (merged) type
528 merged...........the list of merged class types
529 interf...........the interface to check against
532 typecheck_TRUE...the type implement INTERF
533 typecheck_FALSE..the type does not implement INTERF
534 typecheck_MAYBE..check cannot be performed now because of unresolved
536 typecheck_FAIL...an exception has been thrown
538 *******************************************************************************/
540 static typecheck_result
541 merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist_t *merged,
546 /* primitive types don't support interfaces. */
548 return typecheck_FALSE;
550 /* the null type can be cast to any interface type. */
551 if (typeclass == pseudo_class_Null)
552 return typecheck_TRUE;
554 /* check if typeclass implements the interface. */
555 r = classinfo_implements_interface(typeclass,interf);
556 if (r != typecheck_FALSE)
559 /* check the mergedlist */
561 return typecheck_FALSE;
562 return mergedlist_implements_interface(merged,interf);
565 /* merged_is_subclass **********************************************************
567 Check if a possible merged type is a subclass of a given class.
568 A merged type is a subclass of a class C if all types in the merged list
569 are subclasses of C. A sufficient condition for this is that the
570 common type of the merged type is a subclass of C.
573 typeclass........(common) class of the (merged) type
574 MUST be a loaded and linked class
575 merged...........the list of merged class types
576 cls..............the class to theck against
579 typecheck_TRUE...the type is a subclass of CLS
580 typecheck_FALSE..the type is not a subclass of CLS
581 typecheck_MAYBE..check cannot be performed now because of unresolved
583 typecheck_FAIL...an exception has been thrown
585 *******************************************************************************/
587 static typecheck_result
588 merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist_t *merged,
592 classref_or_classinfo *mlist;
594 TYPEINFO_ASSERT(cls);
596 /* primitive types aren't subclasses of anything. */
598 return typecheck_FALSE;
600 /* the null type can be cast to any reference type. */
601 if (typeclass == pseudo_class_Null)
602 return typecheck_TRUE;
604 TYPEINFO_ASSERT(typeclass->state & CLASS_LOADED);
605 TYPEINFO_ASSERT(typeclass->state & CLASS_LINKED);
607 /* check if the common typeclass is a subclass of CLS. */
608 if (class_issubclass(typeclass,cls))
609 return typecheck_TRUE;
611 /* check the mergedlist */
613 return typecheck_FALSE;
614 /* If all classinfos in the (non-empty) merged list are subclasses
615 * of CLS, return true, otherwise false.
616 * If there is at least one unresolved type in the list,
617 * return typecheck_MAYBE.
619 mlist = merged->list;
622 if (IS_CLASSREF(*mlist)) {
623 return typecheck_MAYBE;
625 if (!(mlist->cls->state & CLASS_LINKED))
626 if (!link_class(mlist->cls))
627 return typecheck_FAIL;
628 if (!class_issubclass(mlist->cls,cls))
629 return typecheck_FALSE;
632 return typecheck_TRUE;
635 /* typeinfo_is_assignable_to_class *********************************************
637 Check if a type is assignable to a given class type.
640 value............the type of the value
641 dest.............the type of the destination
644 typecheck_TRUE...the type is assignable
645 typecheck_FALSE..the type is not assignable
646 typecheck_MAYBE..check cannot be performed now because of unresolved
648 typecheck_FAIL...an exception has been thrown
650 *******************************************************************************/
653 typeinfo_is_assignable_to_class(typeinfo_t *value,classref_or_classinfo dest)
655 classref_or_classinfo c;
659 TYPEINFO_ASSERT(value);
661 c = value->typeclass;
663 /* assignments of primitive values are not checked here. */
664 if (!c.any && !dest.any)
665 return typecheck_TRUE;
667 /* primitive and reference types are not assignment compatible. */
668 if (!c.any || !dest.any)
669 return typecheck_FALSE;
671 /* the null type can be assigned to any type */
672 if (TYPEINFO_IS_NULLTYPE(*value))
673 return typecheck_TRUE;
675 /* uninitialized objects are not assignable */
676 if (TYPEINFO_IS_NEWOBJECT(*value))
677 return typecheck_FALSE;
679 if (IS_CLASSREF(c)) {
680 /* The value type is an unresolved class reference. */
681 classname = c.ref->name;
684 classname = c.cls->name;
687 if (IS_CLASSREF(dest)) {
688 /* the destination type is an unresolved class reference */
689 /* In this case we cannot tell a lot about assignability. */
691 /* the common case of value and dest type having the same classname */
692 if (dest.ref->name == classname && !value->merged)
693 return typecheck_TRUE;
695 /* we cannot tell if value is assignable to dest, so we */
696 /* leave it up to the resolving code to check this */
697 return typecheck_MAYBE;
700 /* { we know that dest is a loaded class } */
702 if (IS_CLASSREF(c)) {
703 /* the value type is an unresolved class reference */
705 /* the common case of value and dest type having the same classname */
706 if (dest.cls->name == classname)
707 return typecheck_TRUE;
709 /* we cannot tell if value is assignable to dest, so we */
710 /* leave it up to the resolving code to check this */
711 return typecheck_MAYBE;
714 /* { we know that both c and dest are loaded classes } */
715 /* (c may still have a merged list containing unresolved classrefs!) */
717 TYPEINFO_ASSERT(!IS_CLASSREF(c));
718 TYPEINFO_ASSERT(!IS_CLASSREF(dest));
722 TYPEINFO_ASSERT(cls->state & CLASS_LOADED);
723 TYPEINFO_ASSERT(dest.cls->state & CLASS_LOADED);
725 /* maybe we need to link the classes */
726 if (!(cls->state & CLASS_LINKED))
727 if (!link_class(cls))
728 return typecheck_FAIL;
729 if (!(dest.cls->state & CLASS_LINKED))
730 if (!link_class(dest.cls))
731 return typecheck_FAIL;
733 /* { we know that both c and dest are linked classes } */
734 TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
735 TYPEINFO_ASSERT(dest.cls->state & CLASS_LINKED);
737 if (dest.cls->flags & ACC_INTERFACE) {
738 /* We are assigning to an interface type. */
739 return merged_implements_interface(cls,value->merged,dest.cls);
742 if (CLASSINFO_IS_ARRAY(dest.cls)) {
743 arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
744 int dimension = arraydesc->dimension;
745 classinfo *elementclass = (arraydesc->elementvftbl)
746 ? arraydesc->elementvftbl->clazz : NULL;
748 /* We are assigning to an array type. */
749 if (!TYPEINFO_IS_ARRAY(*value))
750 return typecheck_FALSE;
752 /* {Both value and dest.cls are array types.} */
754 /* value must have at least the dimension of dest.cls. */
755 if (value->dimension < dimension)
756 return typecheck_FALSE;
758 if (value->dimension > dimension) {
759 /* value has higher dimension so we need to check
760 * if its component array can be assigned to the
761 * element type of dest.cls */
763 if (!elementclass) return typecheck_FALSE;
765 if (elementclass->flags & ACC_INTERFACE) {
766 /* We are assigning to an interface type. */
767 return classinfo_implements_interface(pseudo_class_Arraystub,
771 /* We are assigning to a class type. */
772 return class_issubclass(pseudo_class_Arraystub,elementclass);
775 /* {value and dest.cls have the same dimension} */
777 if (value->elementtype != arraydesc->elementtype)
778 return typecheck_FALSE;
780 if (value->elementclass.any) {
781 /* We are assigning an array of objects so we have to
782 * check if the elements are assignable.
785 if (elementclass->flags & ACC_INTERFACE) {
786 /* We are assigning to an interface type. */
788 return merged_implements_interface(value->elementclass.cls,
793 /* We are assigning to a class type. */
794 return merged_is_subclass(value->elementclass.cls,value->merged,elementclass);
797 return typecheck_TRUE;
800 /* {dest.cls is not an array} */
801 /* {dest.cls is a loaded class} */
803 /* If there are any unresolved references in the merged list, we cannot */
804 /* tell if the assignment will be ok. */
805 /* This can only happen when cls is java.lang.Object */
806 if (cls == class_java_lang_Object && value->merged) {
807 classref_or_classinfo *mlist = value->merged->list;
808 int i = value->merged->count;
810 if (IS_CLASSREF(*mlist++))
811 return typecheck_MAYBE;
814 /* We are assigning to a class type */
815 if (cls->flags & ACC_INTERFACE)
816 cls = class_java_lang_Object;
818 return merged_is_subclass(cls,value->merged,dest.cls);
821 /* typeinfo_is_assignable ******************************************************
823 Check if a type is assignable to a given type.
826 value............the type of the value
827 dest.............the type of the destination, must not be a merged type
830 typecheck_TRUE...the type is assignable
831 typecheck_FALSE..the type is not assignable
832 typecheck_MAYBE..check cannot be performed now because of unresolved
834 typecheck_FAIL...an exception has been thrown
836 *******************************************************************************/
839 typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest)
841 TYPEINFO_ASSERT(value);
842 TYPEINFO_ASSERT(dest);
843 TYPEINFO_ASSERT(dest->merged == NULL);
845 return typeinfo_is_assignable_to_class(value,dest->typeclass);
848 /**********************************************************************/
849 /* INITIALIZATION FUNCTIONS */
850 /* The following functions fill in uninitialized typeinfo structures. */
851 /**********************************************************************/
853 /* typeinfo_init_classinfo *****************************************************
855 Initialize a typeinfo to a resolved class.
858 c................the class
861 *info............is initialized
864 true.............success
865 false............an exception has been thrown
867 *******************************************************************************/
870 typeinfo_init_classinfo(typeinfo_t *info, classinfo *c)
872 if ((info->typeclass.cls = c)->vftbl->arraydesc) {
873 if (c->vftbl->arraydesc->elementvftbl)
874 info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->clazz;
876 info->elementclass.any = NULL;
877 info->dimension = c->vftbl->arraydesc->dimension;
878 info->elementtype = c->vftbl->arraydesc->elementtype;
881 info->elementclass.any = NULL;
883 info->elementtype = 0;
888 /* typeinfo_init_class *********************************************************
890 Initialize a typeinfo to a possibly unresolved class type.
893 c................the class type
896 *info............is initialized
899 true.............success
900 false............an exception has been thrown
902 *******************************************************************************/
905 typeinfo_init_class(typeinfo_t *info,classref_or_classinfo c)
911 TYPEINFO_ASSERT(c.any);
912 TYPEINFO_ASSERT(info);
914 /* if necessary, try to resolve lazily */
915 if (!resolve_classref_or_classinfo(NULL /* XXX should know method */,
916 c,resolveLazy,false,true,&cls))
922 typeinfo_init_classinfo(info,cls);
926 /* {the type could no be resolved lazily} */
928 info->typeclass.ref = c.ref;
929 info->elementclass.any = NULL;
933 /* handle array type references */
934 utf_ptr = c.ref->name->text;
935 len = c.ref->name->blength;
936 if (*utf_ptr == '[') {
937 /* count dimensions */
938 while (*utf_ptr == '[') {
943 if (*utf_ptr == 'L') {
946 info->elementtype = ARRAYTYPE_OBJECT;
947 info->elementclass.ref = class_get_classref(c.ref->referer,utf_new(utf_ptr,len));
950 /* an array with primitive element type */
951 /* should have been resolved above */
952 TYPEINFO_ASSERT(false);
958 /* typeinfo_init_from_typedesc *************************************************
960 Initialize a typeinfo from a typedesc.
963 desc.............the typedesc
966 *type............set to the TYPE_* constant of DESC (if type != NULL)
967 *info............receives the typeinfo (if info != NULL)
970 true.............success
971 false............an exception has been thrown
973 *******************************************************************************/
976 typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo_t *info)
978 TYPEINFO_ASSERT(desc);
980 #ifdef TYPEINFO_VERBOSE
981 fprintf(stderr,"typeinfo_init_from_typedesc(");
982 descriptor_debug_print_typedesc(stderr,desc);
983 fprintf(stderr,")\n");
990 if (desc->type == TYPE_ADR) {
991 TYPEINFO_ASSERT(desc->classref);
992 if (!typeinfo_init_class(info,CLASSREF_OR_CLASSINFO(desc->classref)))
996 TYPEINFO_INIT_PRIMITIVE(*info);
1002 /* typeinfos_init_from_methoddesc **********************************************
1004 Initialize an array of typeinfos and u1 TYPE_* values from a methoddesc.
1007 desc.............the methoddesc
1008 buflen...........number of parameters the buffer can hold
1009 twoword..........if true, use two parameter slots for two-word types
1012 *typebuf.........receives a TYPE_* constant for each parameter
1013 typebuf must be != NULL
1014 *infobuf.........receives a typeinfo for each parameter
1015 infobuf must be != NULL
1016 *returntype......receives a TYPE_* constant for the return type
1017 returntype may be NULL
1018 *returntypeinfo..receives a typeinfo for the return type
1019 returntypeinfo may be NULL
1022 true.............success
1023 false............an exception has been thrown
1026 If (according to BUFLEN) the buffers are to small to hold the
1027 parameter types, an internal error is thrown. This must be
1028 avoided by checking the number of parameters and allocating enough
1029 space before calling this function.
1031 *******************************************************************************/
1034 typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo_t *infobuf,
1035 int buflen,bool twoword,
1036 u1 *returntype,typeinfo_t *returntypeinfo)
1041 TYPEINFO_ASSERT(desc);
1042 TYPEINFO_ASSERT(typebuf);
1043 TYPEINFO_ASSERT(infobuf);
1045 #ifdef TYPEINFO_VERBOSE
1046 fprintf(stderr,"typeinfos_init_from_methoddesc(");
1047 descriptor_debug_print_methoddesc(stderr,desc);
1048 fprintf(stderr,")\n");
1051 /* check arguments */
1052 for (i=0; i<desc->paramcount; ++i) {
1053 if (++args > buflen) {
1054 exceptions_throw_internalerror("Buffer too small for method arguments.");
1058 if (!typeinfo_init_from_typedesc(desc->paramtypes + i,typebuf++,infobuf++))
1061 if (twoword && (typebuf[-1] == TYPE_LNG || typebuf[-1] == TYPE_DBL)) {
1062 if (++args > buflen) {
1063 exceptions_throw_internalerror("Buffer too small for method arguments.");
1067 *typebuf++ = TYPE_VOID;
1068 TYPEINFO_INIT_PRIMITIVE(*infobuf);
1073 /* check returntype */
1075 if (!typeinfo_init_from_typedesc(&(desc->returntype),returntype,returntypeinfo))
1082 /* typedescriptor_init_from_typedesc *******************************************
1084 Initialize a typedescriptor from a typedesc.
1087 desc.............the typedesc
1090 *td..............receives the typedescriptor
1094 true.............success
1095 false............an exception has been thrown
1097 *******************************************************************************/
1100 typedescriptor_init_from_typedesc(typedescriptor_t *td,
1103 TYPEINFO_ASSERT(td);
1104 TYPEINFO_ASSERT(desc);
1106 td->type = desc->type;
1107 if (td->type == TYPE_ADR) {
1108 if (!typeinfo_init_class(&(td->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
1112 TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
1117 /* typeinfo_init_varinfo_from_typedesc *****************************************
1119 Initialize a varinfo from a typedesc.
1122 desc.............the typedesc
1125 *var.............receives the type
1129 true.............success
1130 false............an exception has been thrown
1132 *******************************************************************************/
1135 typeinfo_init_varinfo_from_typedesc(varinfo *var,
1138 TYPEINFO_ASSERT(var);
1139 TYPEINFO_ASSERT(desc);
1141 var->type = desc->type;
1142 if (var->type == TYPE_ADR) {
1143 if (!typeinfo_init_class(&(var->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
1147 TYPEINFO_INIT_PRIMITIVE(var->typeinfo);
1152 /* typeinfo_init_varinfos_from_methoddesc **************************************
1154 Initialize an array of varinfos from a methoddesc.
1157 desc.............the methoddesc
1158 buflen...........number of parameters the buffer can hold
1159 startindex.......the zero-based index of the first parameter to
1160 write to the array. In other words the number of
1161 parameters to skip at the beginning of the methoddesc.
1162 map..............map from parameter indices to varinfo indices
1163 (indexed like jitdata.local_map)
1166 *vars............array receiving the varinfos
1167 td[0] receives the type of the
1168 (startindex+1)th parameter of the method
1169 *returntype......receives the typedescriptor of the return type.
1170 returntype may be NULL
1173 true.............everything ok
1174 false............an exception has been thrown
1177 If (according to BUFLEN) the buffer is to small to hold the
1178 parameter types, an internal error is thrown. This must be
1179 avoided by checking the number of parameters and allocating enough
1180 space before calling this function.
1182 *******************************************************************************/
1185 typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
1187 int buflen, int startindex,
1189 typedescriptor_t *returntype)
1196 /* skip arguments */
1197 for (i=0; i<startindex; ++i) {
1199 if (IS_2_WORD_TYPE(desc->paramtypes[i].type))
1203 /* check arguments */
1204 for (i=startindex; i<desc->paramcount; ++i) {
1205 type = desc->paramtypes[i].type;
1206 varindex = map[5*slot + type];
1209 if (IS_2_WORD_TYPE(type))
1212 if (varindex == UNUSED)
1215 if (varindex >= buflen) {
1216 exceptions_throw_internalerror("Buffer too small for method arguments.");
1220 if (!typeinfo_init_varinfo_from_typedesc(vars + varindex, desc->paramtypes + i))
1224 /* check returntype */
1226 if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1233 /* typedescriptors_init_from_methoddesc ****************************************
1235 Initialize an array of typedescriptors from a methoddesc.
1238 desc.............the methoddesc
1239 buflen...........number of parameters the buffer can hold
1240 twoword..........if true, use two parameter slots for two-word types
1241 startindex.......the zero-based index of the first parameter to
1242 write to the array. In other words the number of
1243 parameters to skip at the beginning of the methoddesc.
1246 *td..............array receiving the typedescriptors.
1247 td[0] receives the typedescriptor of the
1248 (startindex+1)th parameter of the method
1249 *returntype......receives the typedescriptor of the return type.
1250 returntype may be NULL
1253 >= 0.............number of typedescriptors filled in TD
1254 -1...............an exception has been thrown
1257 If (according to BUFLEN) the buffer is to small to hold the
1258 parameter types, an internal error is thrown. This must be
1259 avoided by checking the number of parameters and allocating enough
1260 space before calling this function.
1262 *******************************************************************************/
1265 typedescriptors_init_from_methoddesc(typedescriptor_t *td,
1267 int buflen,bool twoword,int startindex,
1268 typedescriptor_t *returntype)
1273 /* check arguments */
1274 for (i=startindex; i<desc->paramcount; ++i) {
1275 if (++args > buflen) {
1276 exceptions_throw_internalerror("Buffer too small for method arguments.");
1280 if (!typedescriptor_init_from_typedesc(td,desc->paramtypes + i))
1284 if (twoword && (td[-1].type == TYPE_LNG || td[-1].type == TYPE_DBL)) {
1285 if (++args > buflen) {
1286 exceptions_throw_internalerror("Buffer too small for method arguments.");
1290 td->type = TYPE_VOID;
1291 TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
1296 /* check returntype */
1298 if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1305 /* typeinfo_init_component *****************************************************
1307 Initialize a typeinfo with the component type of a given array type.
1310 srcarray.........the typeinfo of the array type
1313 *dst.............receives the typeinfo of the component type
1316 true.............success
1317 false............an exception has been thrown
1319 *******************************************************************************/
1322 typeinfo_init_component(typeinfo_t *srcarray,typeinfo_t *dst)
1324 typeinfo_mergedlist_t *merged;
1326 TYPEINFO_ASSERT(srcarray);
1327 TYPEINFO_ASSERT(dst);
1329 if (TYPEINFO_IS_NULLTYPE(*srcarray)) {
1330 TYPEINFO_INIT_NULLTYPE(*dst);
1334 if (!TYPEINFO_IS_ARRAY(*srcarray)) {
1335 /* XXX should we make that a verify error? */
1336 exceptions_throw_internalerror("Trying to access component of non-array");
1340 /* save the mergedlist (maybe dst == srcarray) */
1342 merged = srcarray->merged;
1344 if (IS_CLASSREF(srcarray->typeclass)) {
1345 constant_classref *comp;
1346 comp = class_get_classref_component_of(srcarray->typeclass.ref);
1349 if (!typeinfo_init_class(dst,CLASSREF_OR_CLASSINFO(comp)))
1353 TYPEINFO_INIT_PRIMITIVE(*dst);
1359 if (!(srcarray->typeclass.cls->state & CLASS_LINKED)) {
1360 if (!link_class(srcarray->typeclass.cls)) {
1365 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl);
1366 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl->arraydesc);
1368 comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
1370 typeinfo_init_classinfo(dst,comp->clazz);
1372 TYPEINFO_INIT_PRIMITIVE(*dst);
1375 dst->merged = merged; /* XXX should we do a deep copy? */
1379 /* typeinfo_clone **************************************************************
1381 Create a deep copy of a typeinfo struct.
1384 src..............the typeinfo to copy
1387 *dest............receives the copy
1390 If src == dest this function is a nop.
1392 *******************************************************************************/
1395 typeinfo_clone(typeinfo_t *src,typeinfo_t *dest)
1398 classref_or_classinfo *srclist,*destlist;
1406 count = src->merged->count;
1407 TYPEINFO_ALLOCMERGED(dest->merged,count);
1408 dest->merged->count = count;
1410 srclist = src->merged->list;
1411 destlist = dest->merged->list;
1413 *destlist++ = *srclist++;
1417 /**********************************************************************/
1418 /* MISCELLANEOUS FUNCTIONS */
1419 /**********************************************************************/
1421 /* typeinfo_free ***************************************************************
1423 Free memory referenced by the given typeinfo. The typeinfo itself is not
1427 info.............the typeinfo
1429 *******************************************************************************/
1432 typeinfo_free(typeinfo_t *info)
1434 TYPEINFO_FREEMERGED_IF_ANY(info->merged);
1435 info->merged = NULL;
1438 /**********************************************************************/
1439 /* MERGING FUNCTIONS */
1440 /* The following functions are used to merge the types represented by */
1441 /* two typeinfo structures into one typeinfo structure. */
1442 /**********************************************************************/
1446 typeinfo_merge_error(methodinfo *m,char *str,typeinfo_t *x,typeinfo_t *y) {
1447 #ifdef TYPEINFO_VERBOSE
1448 fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
1449 fprintf(stderr,"Typeinfo x:\n");
1450 typeinfo_print(stderr,x,1);
1451 fprintf(stderr,"Typeinfo y:\n");
1452 typeinfo_print(stderr,y,1);
1456 exceptions_throw_verifyerror(m, str);
1459 /* Condition: clsx != clsy. */
1460 /* Returns: true if dest was changed (currently always true). */
1463 typeinfo_merge_two(typeinfo_t *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
1465 TYPEINFO_ASSERT(dest);
1466 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1467 TYPEINFO_ALLOCMERGED(dest->merged,2);
1468 dest->merged->count = 2;
1470 TYPEINFO_ASSERT(clsx.any != clsy.any);
1472 if (clsx.any < clsy.any) {
1473 dest->merged->list[0] = clsx;
1474 dest->merged->list[1] = clsy;
1477 dest->merged->list[0] = clsy;
1478 dest->merged->list[1] = clsx;
1484 /* Returns: true if dest was changed. */
1487 typeinfo_merge_add(typeinfo_t *dest,typeinfo_mergedlist_t *m,classref_or_classinfo cls)
1490 typeinfo_mergedlist_t *newmerged;
1491 classref_or_classinfo *mlist,*newlist;
1496 /* Check if cls is already in the mergedlist m. */
1498 if ((mlist++)->any == cls.any) { /* XXX check equal classrefs? */
1499 /* cls is in the list, so m is the resulting mergedlist */
1500 if (dest->merged == m)
1503 /* We have to copy the mergedlist */
1504 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1506 TYPEINFO_ALLOCMERGED(dest->merged,count);
1507 dest->merged->count = count;
1508 newlist = dest->merged->list;
1511 *newlist++ = *mlist++;
1517 /* Add cls to the mergedlist. */
1519 TYPEINFO_ALLOCMERGED(newmerged,count+1);
1520 newmerged->count = count+1;
1521 newlist = newmerged->list;
1524 if (mlist->any > cls.any)
1526 *newlist++ = *mlist++;
1531 *newlist++ = *mlist++;
1534 /* Put the new mergedlist into dest. */
1535 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1536 dest->merged = newmerged;
1541 /* Returns: true if dest was changed. */
1544 typeinfo_merge_mergedlists(typeinfo_t *dest,typeinfo_mergedlist_t *x,
1545 typeinfo_mergedlist_t *y)
1549 typeinfo_mergedlist_t *temp,*result;
1550 classref_or_classinfo *clsx,*clsy,*newlist;
1552 /* count the elements that will be in the resulting list */
1553 /* (Both lists are sorted, equal elements are counted only once.) */
1558 while (countx && county) {
1559 if (clsx->any == clsy->any) {
1565 else if (clsx->any < clsy->any) {
1575 count += countx + county;
1577 /* {The new mergedlist will have count entries.} */
1579 if ((x->count != count) && (y->count == count)) {
1580 temp = x; x = y; y = temp;
1582 /* {If one of x,y is already the result it is x.} */
1583 if (x->count == count) {
1584 /* x->merged is equal to the result */
1585 if (x == dest->merged)
1588 if (!dest->merged || dest->merged->count != count) {
1589 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1590 TYPEINFO_ALLOCMERGED(dest->merged,count);
1591 dest->merged->count = count;
1594 newlist = dest->merged->list;
1597 *newlist++ = *clsx++;
1602 /* {We have to merge two lists.} */
1604 /* allocate the result list */
1605 TYPEINFO_ALLOCMERGED(result,count);
1606 result->count = count;
1607 newlist = result->list;
1609 /* merge the sorted lists */
1614 while (countx && county) {
1615 if (clsx->any == clsy->any) {
1616 *newlist++ = *clsx++;
1621 else if (clsx->any < clsy->any) {
1622 *newlist++ = *clsx++;
1626 *newlist++ = *clsy++;
1631 *newlist++ = *clsx++;
1633 *newlist++ = *clsy++;
1635 /* replace the list in dest with the result list */
1636 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1637 dest->merged = result;
1642 /* typeinfo_merge_nonarrays ****************************************************
1644 Merge two non-array types.
1647 x................the first type
1648 y................the second type
1649 mergedx..........merged list of the first type, may be NULL
1650 mergedy..........merged list of the descond type, may be NULL
1653 *dest............receives the resulting merged list
1654 *result..........receives the resulting type
1657 typecheck_TRUE...*dest has been modified
1658 typecheck_FALSE..*dest has not been modified
1659 typecheck_FAIL...an exception has been thrown
1662 RESULT is an extra parameter so it can point to dest->typeclass or to
1665 *******************************************************************************/
1667 static typecheck_result
1668 typeinfo_merge_nonarrays(typeinfo_t *dest,
1669 classref_or_classinfo *result,
1670 classref_or_classinfo x,classref_or_classinfo y,
1671 typeinfo_mergedlist_t *mergedx,
1672 typeinfo_mergedlist_t *mergedy)
1674 classref_or_classinfo t;
1675 classinfo *tcls,*common;
1676 typeinfo_mergedlist_t *tmerged;
1682 TYPEINFO_ASSERT(dest && result && x.any && y.any);
1683 TYPEINFO_ASSERT(x.cls != pseudo_class_Null);
1684 TYPEINFO_ASSERT(y.cls != pseudo_class_Null);
1685 TYPEINFO_ASSERT(x.cls != pseudo_class_New);
1686 TYPEINFO_ASSERT(y.cls != pseudo_class_New);
1688 /*--------------------------------------------------*/
1690 /*--------------------------------------------------*/
1692 /* Common case 1: x and y are the same class or class reference */
1693 /* (This case is very simple unless *both* x and y really represent
1694 * merges of subclasses of clsx==clsy.)
1696 if ( (x.any == y.any) && (!mergedx || !mergedy) ) {
1698 /* DEBUG */ /* log_text("return simple x"); */
1699 changed = (dest->merged != NULL);
1700 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1701 dest->merged = NULL;
1703 /* DEBUG */ /* log_text("returning"); */
1707 xname = (IS_CLASSREF(x)) ? x.ref->name : x.cls->name;
1708 yname = (IS_CLASSREF(y)) ? y.ref->name : y.cls->name;
1710 /* Common case 2: xname == yname, at least one unresolved */
1711 if ((IS_CLASSREF(x) || IS_CLASSREF(y)) && (xname == yname))
1713 /* use the loaded one if any */
1714 if (!IS_CLASSREF(y))
1716 goto return_simple_x;
1719 /*--------------------------------------------------*/
1720 /* non-trivial cases */
1721 /*--------------------------------------------------*/
1723 #ifdef TYPEINFO_VERBOSE
1725 typeinfo_t dbgx,dbgy;
1726 fprintf(stderr,"merge_nonarrays:\n");
1727 fprintf(stderr," ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,xname);fprintf(stderr,"\n");
1728 fprintf(stderr," ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,yname);fprintf(stderr,"\n");
1730 typeinfo_init_class(&dbgx,x);
1731 dbgx.merged = mergedx;
1732 typeinfo_init_class(&dbgy,y);
1733 dbgy.merged = mergedy;
1734 typeinfo_print(stderr,&dbgx,4);
1735 fprintf(stderr," with:\n");
1736 typeinfo_print(stderr,&dbgy,4);
1740 TYPEINFO_ASSERT(IS_CLASSREF(x) || (x.cls->state & CLASS_LOADED));
1741 TYPEINFO_ASSERT(IS_CLASSREF(y) || (y.cls->state & CLASS_LOADED));
1743 /* If y is unresolved or an interface, swap x and y. */
1744 if (IS_CLASSREF(y) || (!IS_CLASSREF(x) && y.cls->flags & ACC_INTERFACE))
1746 t = x; x = y; y = t;
1747 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1750 /* {We know: If only one of x,y is unresolved it is x,} */
1751 /* { If both x,y are resolved and only one of x,y is an interface it is x.} */
1753 if (IS_CLASSREF(x)) {
1754 /* {We know: x and y have different class names} */
1756 /* Check if we are merging an unresolved type with java.lang.Object */
1757 if (y.cls == class_java_lang_Object && !mergedy) {
1759 goto return_simple_x;
1762 common = class_java_lang_Object;
1763 goto merge_with_simple_x;
1766 /* {We know: both x and y are resolved} */
1767 /* {We know: If only one of x,y is an interface it is x.} */
1769 TYPEINFO_ASSERT(!IS_CLASSREF(x) && !IS_CLASSREF(y));
1770 TYPEINFO_ASSERT(x.cls->state & CLASS_LOADED);
1771 TYPEINFO_ASSERT(y.cls->state & CLASS_LOADED);
1773 /* Handle merging of interfaces: */
1774 if (x.cls->flags & ACC_INTERFACE) {
1775 /* {x.cls is an interface and mergedx == NULL.} */
1777 if (y.cls->flags & ACC_INTERFACE) {
1778 /* We are merging two interfaces. */
1779 /* {mergedy == NULL} */
1781 /* {We know that x.cls!=y.cls (see common case at beginning.)} */
1782 result->cls = class_java_lang_Object;
1783 return typeinfo_merge_two(dest,x,y);
1786 /* {We know: x is an interface, y is a class.} */
1788 /* Check if we are merging an interface with java.lang.Object */
1789 if (y.cls == class_java_lang_Object && !mergedy) {
1791 goto return_simple_x;
1794 /* If the type y implements x then the result of the merge
1795 * is x regardless of mergedy.
1798 /* we may have to link the classes */
1799 if (!(x.cls->state & CLASS_LINKED))
1800 if (!link_class(x.cls))
1801 return typecheck_FAIL;
1802 if (!(y.cls->state & CLASS_LINKED))
1803 if (!link_class(y.cls))
1804 return typecheck_FAIL;
1806 TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
1807 TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
1809 if (CLASSINFO_IMPLEMENTS_INTERFACE(y.cls,x.cls->index))
1811 /* y implements x, so the result of the merge is x. */
1812 goto return_simple_x;
1815 r = mergedlist_implements_interface(mergedy,x.cls);
1816 if (r == typecheck_FAIL)
1818 if (r == typecheck_TRUE)
1820 /* y implements x, so the result of the merge is x. */
1821 goto return_simple_x;
1824 /* {We know: x is an interface, the type y a class or a merge
1825 * of subclasses and is not guaranteed to implement x.} */
1827 common = class_java_lang_Object;
1828 goto merge_with_simple_x;
1831 /* {We know: x and y are classes (not interfaces).} */
1833 /* we may have to link the classes */
1834 if (!(x.cls->state & CLASS_LINKED))
1835 if (!link_class(x.cls))
1836 return typecheck_FAIL;
1837 if (!(y.cls->state & CLASS_LINKED))
1838 if (!link_class(y.cls))
1839 return typecheck_FAIL;
1841 TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
1842 TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
1844 /* If *x is deeper in the inheritance hierarchy swap x and y. */
1845 if (x.cls->index > y.cls->index) {
1846 t = x; x = y; y = t;
1847 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1850 /* {We know: y is at least as deep in the hierarchy as x.} */
1852 /* Find nearest common anchestor for the classes. */
1857 while (tcls->index > common->index)
1860 while (common != tcls) {
1861 common = common->super;
1865 /* {common == nearest common anchestor of x and y.} */
1867 /* If x.cls==common and x is a whole class (not a merge of subclasses)
1868 * then the result of the merge is x.
1870 if (x.cls == common && !mergedx) {
1871 goto return_simple_x;
1875 result->cls = common;
1877 return typeinfo_merge_mergedlists(dest,mergedx,mergedy);
1879 return typeinfo_merge_add(dest,mergedx,y);
1882 merge_with_simple_x:
1883 result->cls = common;
1885 return typeinfo_merge_add(dest,mergedy,x);
1887 return typeinfo_merge_two(dest,x,y);
1890 /* typeinfo_merge **************************************************************
1895 m................method for exception messages
1896 dest.............the first type
1897 y................the second type
1900 *dest............receives the result of the merge
1903 typecheck_TRUE...*dest has been modified
1904 typecheck_FALSE..*dest has not been modified
1905 typecheck_FAIL...an exception has been thrown
1908 1) *dest must be a valid initialized typeinfo
1911 *******************************************************************************/
1914 typeinfo_merge(methodinfo *m,typeinfo_t *dest,typeinfo_t* y)
1918 classref_or_classinfo common;
1919 classref_or_classinfo elementclass;
1925 /*--------------------------------------------------*/
1927 /*--------------------------------------------------*/
1929 /* Merging something with itself is a nop */
1931 return typecheck_FALSE;
1933 /* Merging two returnAddress types is ok. */
1934 /* Merging two different returnAddresses never happens, as the verifier */
1935 /* keeps them separate in order to check all the possible return paths */
1936 /* from JSR subroutines. */
1937 if (!dest->typeclass.any && !y->typeclass.any) {
1938 TYPEINFO_ASSERT(TYPEINFO_RETURNADDRESS(*dest) == TYPEINFO_RETURNADDRESS(*y));
1939 return typecheck_FALSE;
1942 /* Primitive types cannot be merged with reference types */
1943 /* This must be checked before calls to typeinfo_merge. */
1944 TYPEINFO_ASSERT(dest->typeclass.any && y->typeclass.any);
1946 /* handle uninitialized object types */
1947 if (TYPEINFO_IS_NEWOBJECT(*dest) || TYPEINFO_IS_NEWOBJECT(*y)) {
1948 if (!TYPEINFO_IS_NEWOBJECT(*dest) || !TYPEINFO_IS_NEWOBJECT(*y)) {
1949 typeinfo_merge_error(m,"Trying to merge uninitialized object type.",dest,y);
1950 return typecheck_FAIL;
1952 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*dest) != TYPEINFO_NEWOBJECT_INSTRUCTION(*y)) {
1953 typeinfo_merge_error(m,"Trying to merge different uninitialized objects.",dest,y);
1954 return typecheck_FAIL;
1956 /* the same uninitialized object -- no change */
1957 return typecheck_FALSE;
1960 /*--------------------------------------------------*/
1962 /*--------------------------------------------------*/
1964 /* Common case: dest and y are the same class or class reference */
1965 /* (This case is very simple unless *both* dest and y really represent
1966 * merges of subclasses of class dest==class y.)
1968 if ((dest->typeclass.any == y->typeclass.any) && (!dest->merged || !y->merged)) {
1970 changed = (dest->merged != NULL);
1971 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1972 dest->merged = NULL;
1976 /* Handle null types: */
1977 if (TYPEINFO_IS_NULLTYPE(*y)) {
1978 return typecheck_FALSE;
1980 if (TYPEINFO_IS_NULLTYPE(*dest)) {
1981 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1982 TYPEINFO_CLONE(*y,*dest);
1983 return typecheck_TRUE;
1986 /* Common case: two types with the same name, at least one unresolved */
1987 if (IS_CLASSREF(dest->typeclass)) {
1988 if (IS_CLASSREF(y->typeclass)) {
1989 if (dest->typeclass.ref->name == y->typeclass.ref->name)
1993 /* XXX should we take y instead of dest here? */
1994 if (dest->typeclass.ref->name == y->typeclass.cls->name)
1999 if (IS_CLASSREF(y->typeclass)
2000 && (dest->typeclass.cls->name == y->typeclass.ref->name))
2006 /*--------------------------------------------------*/
2007 /* non-trivial cases */
2008 /*--------------------------------------------------*/
2010 #ifdef TYPEINFO_VERBOSE
2011 fprintf(stderr,"merge:\n");
2012 typeinfo_print(stderr,dest,4);
2013 typeinfo_print(stderr,y,4);
2016 /* This function uses x internally, so x and y can be swapped
2017 * without changing dest. */
2021 /* Handle merging of arrays: */
2022 if (TYPEINFO_IS_ARRAY(*x) && TYPEINFO_IS_ARRAY(*y)) {
2024 /* Make x the one with lesser dimension */
2025 if (x->dimension > y->dimension) {
2026 tmp = x; x = y; y = tmp;
2029 /* If one array (y) has higher dimension than the other,
2030 * interpret it as an array (same dim. as x) of Arraystubs. */
2031 if (x->dimension < y->dimension) {
2032 dimension = x->dimension;
2033 elementtype = ARRAYTYPE_OBJECT;
2034 elementclass.cls = pseudo_class_Arraystub;
2037 dimension = y->dimension;
2038 elementtype = y->elementtype;
2039 elementclass = y->elementclass;
2042 /* {The arrays are of the same dimension.} */
2044 if (x->elementtype != elementtype) {
2045 /* Different element types are merged, so the resulting array
2046 * type has one accessible dimension less. */
2047 if (--dimension == 0) {
2048 common.cls = pseudo_class_Arraystub;
2050 elementclass.any = NULL;
2053 common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub,true);
2055 exceptions_throw_internalerror("XXX Coult not create array class");
2056 return typecheck_FAIL;
2059 elementtype = ARRAYTYPE_OBJECT;
2060 elementclass.cls = pseudo_class_Arraystub;
2064 /* {The arrays have the same dimension and elementtype.} */
2066 if (elementtype == ARRAYTYPE_OBJECT) {
2067 /* The elements are references, so their respective
2068 * types must be merged.
2070 r = typeinfo_merge_nonarrays(dest,
2074 x->merged,y->merged);
2075 TYPEINFO_ASSERT(r != typecheck_MAYBE);
2076 if (r == typecheck_FAIL)
2080 /* DEBUG */ /* log_text("finding resulting array class: "); */
2081 if (IS_CLASSREF(elementclass))
2082 common.ref = class_get_classref_multiarray_of(dimension,elementclass.ref);
2084 common.cls = class_multiarray_of(dimension,elementclass.cls,true);
2086 exceptions_throw_internalerror("XXX Coult not create array class");
2087 return typecheck_FAIL;
2090 /* DEBUG */ /* utf_display_printable_ascii(common->name); printf("\n"); */
2093 common.any = y->typeclass.any;
2098 /* {We know that at least one of x or y is no array, so the
2099 * result cannot be an array.} */
2101 r = typeinfo_merge_nonarrays(dest,
2103 x->typeclass,y->typeclass,
2104 x->merged,y->merged);
2105 TYPEINFO_ASSERT(r != typecheck_MAYBE);
2106 if (r == typecheck_FAIL)
2112 elementclass.any = NULL;
2115 /* Put the new values into dest if neccessary. */
2117 if (dest->typeclass.any != common.any) {
2118 dest->typeclass.any = common.any;
2121 if (dest->dimension != dimension) {
2122 dest->dimension = dimension;
2125 if (dest->elementtype != elementtype) {
2126 dest->elementtype = elementtype;
2129 if (dest->elementclass.any != elementclass.any) {
2130 dest->elementclass.any = elementclass.any;
2136 #endif /* ENABLE_VERIFER */
2139 /**********************************************************************/
2140 /* DEBUGGING HELPERS */
2141 /**********************************************************************/
2143 #ifdef TYPEINFO_DEBUG
2147 typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
2149 if (a->any == b->any) return 0;
2150 if (a->any < b->any) return -1;
2155 typeinfo_test_parse(typeinfo_t *info,char *str)
2159 typeinfo_t *infobuf;
2162 utf *desc = utf_new_char(str);
2164 num = typeinfo_count_method_args(desc,false);
2166 typebuf = DMNEW(u1,num);
2167 infobuf = DMNEW(typeinfo_t,num);
2169 typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
2172 TYPEINFO_ALLOCMERGED(info->merged,num);
2173 info->merged->count = num;
2175 for (i=0; i<num; ++i) {
2176 if (typebuf[i] != TYPE_ADR) {
2177 log_text("non-reference type in mergedlist");
2181 info->merged->list[i].any = infobuf[i].typeclass.any;
2183 qsort(info->merged->list,num,sizeof(classref_or_classinfo),
2184 (int(*)(const void *,const void *))&typeinfo_test_compare);
2187 typeinfo_init_from_method_args(desc,NULL,NULL,0,false,
2193 #define TYPEINFO_TEST_BUFLEN 4000
2196 typeinfo_equal(typeinfo_t *x,typeinfo_t *y)
2200 if (x->typeclass.any != y->typeclass.any) return false;
2201 if (x->dimension != y->dimension) return false;
2203 if (x->elementclass.any != y->elementclass.any) return false;
2204 if (x->elementtype != y->elementtype) return false;
2207 if (TYPEINFO_IS_NEWOBJECT(*x))
2208 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*x)
2209 != TYPEINFO_NEWOBJECT_INSTRUCTION(*y))
2212 if (x->merged || y->merged) {
2213 if (!(x->merged && y->merged)) return false;
2214 if (x->merged->count != y->merged->count) return false;
2215 for (i=0; i<x->merged->count; ++i)
2216 if (x->merged->list[i].any != y->merged->list[i].any)
2223 typeinfo_testmerge(typeinfo_t *a,typeinfo_t *b,typeinfo_t *result,int *failed)
2226 bool changed,changed_should_be;
2229 TYPEINFO_CLONE(*a,dest);
2232 typeinfo_print_short(stdout,&dest);
2234 typeinfo_print_short(stdout,b);
2237 r = typeinfo_merge(NULL,&dest,b);
2238 if (r == typecheck_FAIL) {
2239 printf("EXCEPTION\n");
2242 changed = (r) ? 1 : 0;
2243 changed_should_be = (!typeinfo_equal(&dest,a)) ? 1 : 0;
2245 printf(" %s\n",(changed) ? "changed" : "=");
2247 if (typeinfo_equal(&dest,result)) {
2249 typeinfo_print_short(stdout,&dest);
2251 if (changed != changed_should_be) {
2252 printf("WRONG RETURN VALUE!\n");
2258 typeinfo_print_short(stdout,&dest);
2260 printf("SHOULD BE ");
2261 typeinfo_print_short(stdout,result);
2269 typeinfo_inc_dimension(typeinfo_t *info)
2271 if (info->dimension++ == 0) {
2272 info->elementtype = ARRAYTYPE_OBJECT;
2273 info->elementclass = info->typeclass;
2275 info->typeclass = class_array_of(info->typeclass,true);
2279 #define TYPEINFO_TEST_MAXDIM 10
2282 typeinfo_testrun(char *filename)
2284 char buf[TYPEINFO_TEST_BUFLEN];
2285 char bufa[TYPEINFO_TEST_BUFLEN];
2286 char bufb[TYPEINFO_TEST_BUFLEN];
2287 char bufc[TYPEINFO_TEST_BUFLEN];
2291 FILE *file = fopen(filename,"rt");
2295 log_text("could not open typeinfo test file");
2299 while (fgets(buf,TYPEINFO_TEST_BUFLEN,file)) {
2300 if (buf[0] == '#' || !strlen(buf))
2303 res = sscanf(buf,"%s\t%s\t%s\n",bufa,bufb,bufc);
2304 if (res != 3 || !strlen(bufa) || !strlen(bufb) || !strlen(bufc)) {
2305 log_text("Invalid line in typeinfo test file (none of empty, comment or test)");
2310 typeinfo_test_parse(&a,bufa);
2311 typeinfo_test_parse(&b,bufb);
2312 typeinfo_test_parse(&c,bufc);
2317 typeinfo_testmerge(&a,&b,&c,&failed); /* check result */
2318 typeinfo_testmerge(&b,&a,&c,&failed); /* check commutativity */
2320 if (TYPEINFO_IS_NULLTYPE(a)) break;
2321 if (TYPEINFO_IS_NULLTYPE(b)) break;
2322 if (TYPEINFO_IS_NULLTYPE(c)) break;
2324 maxdim = a.dimension;
2325 if (b.dimension > maxdim) maxdim = b.dimension;
2326 if (c.dimension > maxdim) maxdim = c.dimension;
2329 if (maxdim < TYPEINFO_TEST_MAXDIM) {
2330 typeinfo_inc_dimension(&a);
2331 typeinfo_inc_dimension(&b);
2332 typeinfo_inc_dimension(&c);
2334 } while (maxdim < TYPEINFO_TEST_MAXDIM);
2341 fprintf(stderr,"Failed typeinfo_merge tests: %d\n",failed);
2342 log_text("Failed test");
2350 log_text("Running typeinfo test file...");
2351 typeinfo_testrun("typeinfo.tst");
2352 log_text("Finished typeinfo test file.");
2357 typeinfo_init_from_fielddescriptor(typeinfo_t *info,char *desc)
2359 typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
2363 #define TYPEINFO_MAXINDENT 80
2366 typeinfo_print_class(FILE *file,classref_or_classinfo c)
2368 /*fprintf(file,"<class %p>",c.any);*/
2371 fprintf(file,"<null>");
2374 if (IS_CLASSREF(c)) {
2375 fprintf(file,"<ref>");
2376 utf_fprint_printable_ascii(file,c.ref->name);
2379 utf_fprint_printable_ascii(file,c.cls->name);
2385 typeinfo_print(FILE *file,typeinfo_t *info,int indent)
2388 char ind[TYPEINFO_MAXINDENT + 1];
2392 if (indent > TYPEINFO_MAXINDENT) indent = TYPEINFO_MAXINDENT;
2394 for (i=0; i<indent; ++i)
2398 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2399 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2401 fprintf(file,"%sreturnAddress (L%03d)\n",ind,bptr->nr);
2403 fprintf(file,"%sprimitive\n",ind);
2407 if (TYPEINFO_IS_NULLTYPE(*info)) {
2408 fprintf(file,"%snull\n",ind);
2412 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2413 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2415 fprintf(file,"%sNEW(%p):",ind,(void*)ins);
2416 typeinfo_print_class(file,ins[-1].sx.val.c);
2420 fprintf(file,"%sNEW(this)",ind);
2425 fprintf(file,"%sClass: ",ind);
2426 typeinfo_print_class(file,info->typeclass);
2429 if (TYPEINFO_IS_ARRAY(*info)) {
2430 fprintf(file,"%sDimension: %d",ind,(int)info->dimension);
2431 fprintf(file,"\n%sElements: ",ind);
2432 switch (info->elementtype) {
2433 case ARRAYTYPE_INT : fprintf(file,"int\n"); break;
2434 case ARRAYTYPE_LONG : fprintf(file,"long\n"); break;
2435 case ARRAYTYPE_FLOAT : fprintf(file,"float\n"); break;
2436 case ARRAYTYPE_DOUBLE : fprintf(file,"double\n"); break;
2437 case ARRAYTYPE_BYTE : fprintf(file,"byte\n"); break;
2438 case ARRAYTYPE_CHAR : fprintf(file,"char\n"); break;
2439 case ARRAYTYPE_SHORT : fprintf(file,"short\n"); break;
2440 case ARRAYTYPE_BOOLEAN : fprintf(file,"boolean\n"); break;
2442 case ARRAYTYPE_OBJECT:
2443 typeinfo_print_class(file,info->elementclass);
2448 fprintf(file,"INVALID ARRAYTYPE!\n");
2453 fprintf(file,"%sMerged: ",ind);
2454 for (i=0; i<info->merged->count; ++i) {
2455 if (i) fprintf(file,", ");
2456 typeinfo_print_class(file,info->merged->list[i]);
2463 typeinfo_print_short(FILE *file,typeinfo_t *info)
2469 /*fprintf(file,"<typeinfo %p>",info);*/
2472 fprintf(file,"(typeinfo*)NULL");
2476 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2477 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2479 fprintf(file,"ret(L%03d)",bptr->nr);
2481 fprintf(file,"primitive");
2485 if (TYPEINFO_IS_NULLTYPE(*info)) {
2486 fprintf(file,"null");
2490 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2491 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2493 /*fprintf(file,"<ins %p>",ins);*/
2494 fprintf(file,"NEW(%p):",(void*)ins);
2495 typeinfo_print_class(file,ins[-1].sx.val.c);
2498 fprintf(file,"NEW(this)");
2502 typeinfo_print_class(file,info->typeclass);
2506 for (i=0; i<info->merged->count; ++i) {
2507 if (i) fprintf(file,",");
2508 typeinfo_print_class(file,info->merged->list[i]);
2515 typeinfo_print_type(FILE *file,int type,typeinfo_t *info)
2518 case TYPE_VOID: fprintf(file,"V"); break;
2519 case TYPE_INT: fprintf(file,"I"); break;
2520 case TYPE_FLT: fprintf(file,"F"); break;
2521 case TYPE_DBL: fprintf(file,"D"); break;
2522 case TYPE_LNG: fprintf(file,"J"); break;
2523 case TYPE_RET: fprintf(file,"R:"); /* FALLTHROUGH! */
2525 typeinfo_print_short(file,info);
2534 typedescriptor_print(FILE *file,typedescriptor_t *td)
2536 typeinfo_print_type(file,td->type,&(td->typeinfo));
2540 typevector_print(FILE *file,varinfo *vec,int size)
2544 for (i=0; i<size; ++i) {
2545 fprintf(file," %d=",i);
2546 typeinfo_print_type(file, vec[i].type, &(vec[i].typeinfo));
2550 #endif /* TYPEINFO_DEBUG */
2554 * These are local overrides for various environment variables in Emacs.
2555 * Please do not remove this and leave it at the end of the file, where
2556 * Emacs will automagically detect them.
2557 * ---------------------------------------------------------------------
2560 * indent-tabs-mode: t
2564 * vim:noexpandtab:sw=4:ts=4: