1 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Edwin Steiner
29 $Id: typeinfo.c 2803 2005-06-23 13:19:41Z twisti $
36 #include "mm/memory.h"
37 #include "toolbox/logging.h"
39 #include "vm/loader.h"
40 #include "vm/tables.h"
41 #include "vm/jit/jit.h"
42 #include "vm/jit/verify/typeinfo.h"
43 #include "vm/descriptor.h"
44 #include "vm/resolve.h"
47 /* check if a linked class is an array class. Only use for linked classes! */
48 #define CLASSINFO_IS_ARRAY(clsinfo) ((clsinfo)->vftbl->arraydesc != NULL)
50 #define CLASSINFO_IMPLEMENTS_INTERFACE(cls,index) \
51 ( ((index) < (cls)->vftbl->interfacetablelength) \
52 && (VFTBLINTERFACETABLE((cls)->vftbl,(index)) != NULL) )
54 /******************************************************************************/
56 /******************************************************************************/
59 #define TYPEINFO_ASSERT(cond) assert(cond)
61 #define TYPEINFO_ASSERT(cond)
64 /**********************************************************************/
65 /* TYPEVECTOR FUNCTIONS */
66 /**********************************************************************/
68 /* typevectorset_copy **********************************************************
70 Return a copy of the given typevector set.
73 src..............typevector set to copy, must be != NULL
74 k................k-index to set in first typevector of resulting set
75 size.............number of elements per typevector
78 a pointer to the new typevector set
81 This function recursively invokes itself with increasing k-index to
82 copy the alternative typevectors in the given set.
84 *******************************************************************************/
87 typevectorset_copy(typevector *src,int k,int size)
89 typevector *dst = DNEW_TYPEVECTOR(size);
93 memcpy(dst,src,TYPEVECTOR_SIZE(size));
96 dst->alt = typevectorset_copy(src->alt,k+1,size);
100 /* typevectorset_checktype *****************************************************
102 Check if all typevectors contain a given type at a given index.
105 vec..............typevector set, must be != NULL
106 index............index of component to check
107 type.............TYPE_* constant to check against
110 true if all typevectors in the set contain TYPE at INDEX,
113 *******************************************************************************/
116 typevectorset_checktype(typevector *vec,int index,int type)
118 TYPEINFO_ASSERT(vec);
120 if (vec->td[index].type != type)
122 } while ((vec = vec->alt) != NULL);
126 /* typevectorset_checkreference ************************************************
128 Check if all typevectors contain a reference at a given index.
131 vec..............typevector set, must be != NULL
132 index............index of component to check
135 true if all typevectors in the set contain a reference at INDEX,
138 *******************************************************************************/
141 typevectorset_checkreference(typevector *vec,int index)
143 TYPEINFO_ASSERT(vec);
145 if (!TYPEDESC_IS_REFERENCE(vec->td[index]))
147 } while ((vec = vec->alt) != NULL);
151 /* typevectorset_checkretaddr **************************************************
153 Check if all typevectors contain a returnAddress at a given index.
156 vec..............typevector set, must be != NULL
157 index............index of component to check
160 true if all typevectors in the set contain a returnAddress at INDEX,
163 *******************************************************************************/
166 typevectorset_checkretaddr(typevector *vec,int index)
168 TYPEINFO_ASSERT(vec);
170 if (!TYPEDESC_IS_RETURNADDRESS(vec->td[index]))
172 } while ((vec = vec->alt) != NULL);
176 /* typevectorset_copymergedtype ************************************************
178 Merge the types at a given index in the typevectors of a set and
179 copy the result to a destination typeinfo.
182 vec..............typevector set, must be != NULL
183 index............index of component to merge
186 *dst.............destination typeinfo, receives the merge result
189 the TYPE_* constant of the resulting type
190 TYPE_VOID if incompatible types were contained at INDEX in VEC
192 *******************************************************************************/
195 typevectorset_copymergedtype(typevector *vec,int index,typeinfo *dst)
200 TYPEINFO_ASSERT(vec);
201 TYPEINFO_ASSERT(dst);
203 td = vec->td + index;
205 TYPEINFO_COPY(td->info,*dst);
210 primitive = TYPEINFO_IS_PRIMITIVE(*dst) ? 1 : 0;
212 while ((vec = vec->alt) != NULL) {
213 td = vec->td + index;
214 if (type != td->type)
217 if (type == TYPE_ADDRESS) {
218 if ((TYPEINFO_IS_PRIMITIVE(td->info) ? 1 : 0) != primitive)
220 /* there cannot be any merge errors now. In the worst case */
221 /* we either get a returnAddress type or a j.l.O reference */
222 typeinfo_merge(dst,&(td->info));
229 /* typevectorset_mergedtype ****************************************************
231 Return the merged type of the types at a given index in the typevectors
235 vec..............typevector set, must be != NULL
236 index............index of component to merge
237 temp.............pointer to a typeinfo that may be used to merge the
241 *result..........set to the address of a typeinfo containing the
245 the TYPE_* constant of the resulting type
246 TYPE_VOID if incompatible types were contained at INDEX in VEC
249 This function should be more efficient than typevectorset_copymergedtype
250 assuming that most typevector sets contain exactly one typevector.
252 *******************************************************************************/
255 typevectorset_mergedtype(typevector *vec,int index,typeinfo *temp,typeinfo **result)
257 TYPEINFO_ASSERT(vec);
258 TYPEINFO_ASSERT(temp);
259 TYPEINFO_ASSERT(result);
263 return typevectorset_copymergedtype(vec,index,temp);
266 *result = &(vec->td[index].info);
267 return vec->td[index].type;
270 /* typevectorset_mergedtypeinfo ************************************************
272 This is a convenience wrapper around typevectorset_mergedtype. Use this if
273 you are only interested in TYPE_ADR results.
276 vec..............typevector set, must be != NULL
277 index............index of component to merge
278 temp.............pointer to a typeinfo that may be used to merge the
282 a pointer to the resulting typeinfo, or
283 NULL if the result is not a TYPE_ADR type
285 *******************************************************************************/
288 typevectorset_mergedtypeinfo(typevector *vec,int index,typeinfo *temp)
291 int type = typevectorset_mergedtype(vec,index,temp,&result);
292 return (type == TYPE_ADDRESS) ? result : NULL;
295 /* typevectorset_store *********************************************************
297 Store a type at a given index in the typevectors of a set.
298 This function stores the same type in all typevectors of the set.
299 DO NOT use it to store returnAddress types!
300 DO NOT use it to store two-word types!
303 vec..............typevector set, must be != NULL
304 index............index of component to set
305 type.............TYPE_* constant of type to set
306 info.............typeinfo of type to set, may be NULL,
310 If there is a two-word type stored at INDEX-1 in any typevector, it is
311 changed to TYPE_VOID (because its upper half has become invalid).
313 The components at INDEX+1 are _not_ touched, regardless of TYPE.
315 *******************************************************************************/
318 typevectorset_store(typevector *vec,int index,int type,typeinfo *info)
320 TYPEINFO_ASSERT(vec);
321 TYPEINFO_ASSERT((info && !TYPEINFO_IS_PRIMITIVE(*info)) || type != TYPE_ADR);
324 vec->td[index].type = type;
326 TYPEINFO_COPY(*info,vec->td[index].info);
327 if (index > 0 && IS_2_WORD_TYPE(vec->td[index-1].type))
328 vec->td[index-1].type = TYPE_VOID;
329 } while ((vec = vec->alt) != NULL);
332 /* typevectorset_store_retaddr *************************************************
334 Store a returnAddress type at a given index in the typevectors of a set.
335 Each possible returnAddress of the type is stored in the corresponding
336 typevector of the set.
339 vec..............typevector set, must be != NULL
340 index............index of component to set
341 info.............typeinfo of the returnAddress. This typeinfo must
342 contain a return address set with at least as many
343 entries as there are typevectors in VEC.
346 If there is a two-word type stored at INDEX-1 in any typevector, it is
347 changed to TYPE_VOID (because its upper half has become invalid).
349 *******************************************************************************/
352 typevectorset_store_retaddr(typevector *vec,int index,typeinfo *info)
354 typeinfo_retaddr_set *adr;
356 TYPEINFO_ASSERT(vec);
357 TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
359 adr = (typeinfo_retaddr_set*) TYPEINFO_RETURNADDRESS(*info);
361 TYPEINFO_ASSERT(adr);
363 vec->td[index].type = TYPE_ADDRESS;
364 TYPEINFO_INIT_RETURNADDRESS(vec->td[index].info,adr->addr);
365 if (index > 0 && IS_2_WORD_TYPE(vec->td[index-1].type))
366 vec->td[index-1].type = TYPE_VOID;
368 } while ((vec = vec->alt) != NULL);
371 /* typevectorset_store_twoword *************************************************
373 Store a two-word type at a given index in the typevectors of a set.
374 This function stores the same type in all typevectors of the set.
377 vec..............typevector set, must be != NULL
378 index............index of component to set
379 type.............TYPE_* constant of type to set (TYPE_LONG, TYPE_DOUBLE)
382 If there is a two-word type stored at INDEX-1 in any typevector, it is
383 changed to TYPE_VOID (because its upper half has become invalid).
385 The components at INDEX+1 are set to TYPE_VOID.
387 *******************************************************************************/
390 typevectorset_store_twoword(typevector *vec,int index,int type)
392 TYPEINFO_ASSERT(vec);
393 TYPEINFO_ASSERT(type == TYPE_LONG || type == TYPE_DOUBLE);
396 vec->td[index].type = type;
397 vec->td[index+1].type = TYPE_VOID;
398 if (index > 0 && IS_2_WORD_TYPE(vec->td[index-1].type))
399 vec->td[index-1].type = TYPE_VOID;
400 } while ((vec = vec->alt) != NULL);
403 /* typevectorset_init_object ***************************************************
405 Replace all uninitialized object types in the typevector set which were
406 created by the given instruction by initialized object types.
409 set..............typevector set
410 ins..............instruction which created the uninitialized object type
411 initclass........class of the initialized object type to set
412 size.............number of elements per typevector
415 true.............success
416 false............an exception has been thrown
418 XXX maybe we should do the lazy resolving before calling this function
420 *******************************************************************************/
423 typevectorset_init_object(typevector *set,void *ins,
424 classref_or_classinfo initclass,
429 for (;set; set=set->alt) {
430 for (i=0; i<size; ++i) {
431 if (set->td[i].type == TYPE_ADR
432 && TYPEINFO_IS_NEWOBJECT(set->td[i].info)
433 && TYPEINFO_NEWOBJECT_INSTRUCTION(set->td[i].info) == ins)
435 if (!typeinfo_init_class(&(set->td[i].info),initclass))
443 /* typevector_merge ************************************************************
445 Merge a typevector with another one.
446 The given typevectors must have the same number of components.
449 dst..............the first typevector
450 y................the second typevector
451 size.............number of elements per typevector
454 *dst.............the resulting typevector
457 true.............dst has been modified
458 false............dst has not been modified
460 *******************************************************************************/
463 typevector_merge(typevector *dst,typevector *y,int size)
465 bool changed = false;
467 typedescriptor *a = dst->td;
468 typedescriptor *b = y->td;
470 if (a->type != TYPE_VOID && a->type != b->type) {
474 else if (a->type == TYPE_ADDRESS) {
475 if (TYPEINFO_IS_PRIMITIVE(a->info)) {
476 /* 'a' is a returnAddress */
477 if (!TYPEINFO_IS_PRIMITIVE(b->info)
478 || (TYPEINFO_RETURNADDRESS(a->info)
479 != TYPEINFO_RETURNADDRESS(b->info)))
486 /* 'a' is a reference */
487 if (TYPEINFO_IS_PRIMITIVE(b->info)) {
492 /* two reference types are merged. There cannot be */
493 /* a merge error. In the worst case we get j.l.O. */
494 changed |= typeinfo_merge(&(a->info),&(b->info));
504 /* typevector_separable_from ***************************************************
506 Check if two typevectors are separable. Two typevectors are considered
507 separable if there is an index i for which both typevectors contain a
508 returnAddress type and the return addresses of the types are different.
509 The typevectors must have the same number of components.
512 a................the first typevector
513 b................the second typevector
514 size.............number of elements per typevector
517 true.............typevectors are separable
518 false............typevectors are not separable
520 *******************************************************************************/
523 typevector_separable_from(typevector *a,typevector *b,int size)
525 typedescriptor *tda = a->td;
526 typedescriptor *tdb = b->td;
527 for (;size--; tda++,tdb++) {
528 if (TYPEDESC_IS_RETURNADDRESS(*tda)
529 && TYPEDESC_IS_RETURNADDRESS(*tdb)
530 && TYPEINFO_RETURNADDRESS(tda->info)
531 != TYPEINFO_RETURNADDRESS(tdb->info))
537 /* typevectorset_add ***********************************************************
539 Add a typevector to a typevector set. The typevector is added at the end of
540 the set and the k-index of the typevector is set accordingly.
543 dst..............the typevector set to modify
544 v................the typevector to add
545 size.............number of elements per typevector
547 *******************************************************************************/
550 typevectorset_add(typevector *dst,typevector *v,int size)
552 TYPEINFO_ASSERT(dst);
557 dst->alt = DNEW_TYPEVECTOR(size);
558 memcpy(dst->alt,v,TYPEVECTOR_SIZE(size));
559 dst->alt->alt = NULL;
560 dst->alt->k = dst->k + 1;
563 /* typevectorset_select ********************************************************
565 Pick the typevectors from a set which contain a given return address.
568 set..............points to the location containing the typevector set.
570 index............index to check against the return address. All
571 typevectors must contain a returnAddress type at
573 retaddr..........the return address to select
576 *set.............receives the typevector set after removing the
577 selected typevectors.
580 a typevector set consisting of the selected typevectors.
582 *******************************************************************************/
585 typevectorset_select(typevector **set,int index,void *retaddr)
587 typevector *selected;
589 if (!*set) return NULL;
591 if (TYPEINFO_RETURNADDRESS((*set)->td[index].info) == retaddr) {
593 *set = selected->alt;
594 selected->alt = typevectorset_select(set,index,retaddr);
597 selected = typevectorset_select(&((*set)->alt),index,retaddr);
602 /* typevector_separable_with ***************************************************
604 Check if a typevector set would be separable after adding a given
605 typevector. A typevector set is considered separable if there is an
606 index i for which all typevectors in the set contain a returnAddress type,
607 and at least two different return addresses occurr at index i.
608 The typevectors must have the same number of components.
611 set..............the typevector set
612 add..............the typevector
613 size.............number of elements per typevector
616 true.............result would be separable
617 false............result would not be separable
619 *******************************************************************************/
622 typevectorset_separable_with(typevector *set,typevector *add,int size)
629 TYPEINFO_ASSERT(set);
630 TYPEINFO_ASSERT(add);
632 for (i=0; i<size; ++i) {
633 if (!TYPEDESC_IS_RETURNADDRESS(add->td[i]))
635 addr = TYPEINFO_RETURNADDRESS(add->td[i].info);
640 if (!TYPEDESC_IS_RETURNADDRESS(v->td[i]))
642 if (TYPEINFO_RETURNADDRESS(v->td[i].info) != addr)
646 if (separable) return true;
653 /* typevectorset_collapse ******************************************************
655 Collapse a typevector set into a single typevector by merging the
656 components of the typevectors at each index.
659 dst..............the type vector set
660 size.............number of elements per typevector
663 *dst.............the resulting typevector set (a single typevector)
666 true.............dst has been modified
667 false............dst has not been modified
669 *******************************************************************************/
672 typevectorset_collapse(typevector *dst,int size)
674 bool changed = false;
676 TYPEINFO_ASSERT(dst);
679 typevector_merge(dst,dst->alt,size);
680 dst->alt = dst->alt->alt;
686 /**********************************************************************/
687 /* READ-ONLY FUNCTIONS */
688 /* The following functions don't change typeinfo data. */
689 /**********************************************************************/
692 typeinfo_is_array(typeinfo *info)
694 TYPEINFO_ASSERT(info);
695 return TYPEINFO_IS_ARRAY(*info);
699 typeinfo_is_primitive_array(typeinfo *info,int arraytype)
701 TYPEINFO_ASSERT(info);
702 return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
706 typeinfo_is_array_of_refs(typeinfo *info)
708 TYPEINFO_ASSERT(info);
709 return TYPEINFO_IS_ARRAY_OF_REFS(*info);
713 interface_extends_interface(classinfo *cls,classinfo *interf)
717 TYPEINFO_ASSERT(cls);
718 TYPEINFO_ASSERT(interf);
719 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
720 TYPEINFO_ASSERT((cls->flags & ACC_INTERFACE) != 0);
721 TYPEINFO_ASSERT(cls->linked);
723 /* first check direct superinterfaces */
724 for (i=0; i<cls->interfacescount; ++i) {
725 if (cls->interfaces[i].cls == interf)
729 /* check indirect superinterfaces */
730 for (i=0; i<cls->interfacescount; ++i) {
731 if (interface_extends_interface(cls->interfaces[i].cls,interf))
739 classinfo_implements_interface(classinfo *cls,classinfo *interf)
741 TYPEINFO_ASSERT(cls);
742 TYPEINFO_ASSERT(interf);
743 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
746 if (!link_class(cls)) /* XXX */
749 if (cls->flags & ACC_INTERFACE) {
750 /* cls is an interface */
754 /* check superinterfaces */
755 return interface_extends_interface(cls,interf);
758 return CLASSINFO_IMPLEMENTS_INTERFACE(cls,interf->index);
762 mergedlist_implements_interface(typeinfo_mergedlist *merged,
766 classref_or_classinfo *mlist;
768 TYPEINFO_ASSERT(interf);
769 TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
771 /* Check if there is an non-empty mergedlist. */
775 /* If all classinfos in the (non-empty) merged array implement the
776 * interface return true, otherwise false.
778 mlist = merged->list;
781 if (IS_CLASSREF(*mlist)) {
784 if (!classinfo_implements_interface((mlist++)->cls,interf))
791 merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
794 /* primitive types don't support interfaces. */
798 /* the null type can be cast to any interface type. */
799 if (typeclass == pseudo_class_Null)
802 /* check if typeclass implements the interface. */
803 if (classinfo_implements_interface(typeclass,interf))
806 /* check the mergedlist */
807 return (merged && mergedlist_implements_interface(merged,interf));
811 typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
813 TYPEINFO_ASSERT(value);
814 TYPEINFO_ASSERT(dest);
815 TYPEINFO_ASSERT(dest->merged == NULL);
817 return typeinfo_is_assignable_to_class(value,dest->typeclass);
821 typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
823 classref_or_classinfo c;
827 TYPEINFO_ASSERT(value);
829 c = value->typeclass;
831 /* assignments of primitive values are not checked here. */
832 if (!c.any && !dest.any)
835 /* primitive and reference types are not assignment compatible. */
836 if (!c.any || !dest.any)
839 /* the null type can be assigned to any type */
840 if (TYPEINFO_IS_NULLTYPE(*value))
843 /* uninitialized objects are not assignable */
844 if (TYPEINFO_IS_NEWOBJECT(*value))
847 if (IS_CLASSREF(c)) {
848 /* The value type is an unresolved class reference. */
849 classname = c.ref->name;
852 classname = c.cls->name;
855 if (IS_CLASSREF(dest)) {
856 /* the destination type is an unresolved class reference */
857 /* In this case we cannot tell a lot about assignability. */
859 /* the common case of value and dest type having the same classname */
860 if (dest.ref->name == classname && !value->merged)
863 /* we cannot tell if value is assignable to dest, so we */
864 /* leave it up to the resolving code to check this */
868 /* { we know that dest is a loaded class } */
870 if (IS_CLASSREF(c)) {
871 /* the value type is an unresolved class reference */
873 /* the common case of value and dest type having the same classname */
874 if (dest.cls->name == classname)
877 /* we cannot tell if value is assignable to dest, so we */
878 /* leave it up to the resolving code to check this */
882 /* { we know that both c and dest are loaded classes } */
884 TYPEINFO_ASSERT(!IS_CLASSREF(c));
885 TYPEINFO_ASSERT(!IS_CLASSREF(dest));
889 TYPEINFO_ASSERT(cls->loaded);
890 TYPEINFO_ASSERT(dest.cls->loaded);
892 /* maybe we need to link the classes */
894 link_class(cls); /* XXX */
895 if (!dest.cls->linked)
896 link_class(dest.cls); /* XXX */
898 /* { we know that both c and dest are linked classes } */
899 TYPEINFO_ASSERT(cls->linked);
900 TYPEINFO_ASSERT(dest.cls->linked);
902 if (dest.cls->flags & ACC_INTERFACE) {
903 /* We are assigning to an interface type. */
904 return merged_implements_interface(cls,value->merged,dest.cls);
907 if (CLASSINFO_IS_ARRAY(dest.cls)) {
908 arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
909 int dimension = arraydesc->dimension;
910 classinfo *elementclass = (arraydesc->elementvftbl)
911 ? arraydesc->elementvftbl->class : NULL;
913 /* We are assigning to an array type. */
914 if (!TYPEINFO_IS_ARRAY(*value))
917 /* {Both value and dest.cls are array types.} */
919 /* value must have at least the dimension of dest.cls. */
920 if (value->dimension < dimension)
923 if (value->dimension > dimension) {
924 /* value has higher dimension so we need to check
925 * if its component array can be assigned to the
926 * element type of dest.cls */
928 if (!elementclass) return false;
930 if (elementclass->flags & ACC_INTERFACE) {
931 /* We are assigning to an interface type. */
932 return classinfo_implements_interface(pseudo_class_Arraystub,
936 /* We are assigning to a class type. */
937 return class_issubclass(pseudo_class_Arraystub,elementclass);
940 /* {value and dest.cls have the same dimension} */
942 if (value->elementtype != arraydesc->elementtype)
945 if (value->elementclass.any) {
946 /* We are assigning an array of objects so we have to
947 * check if the elements are assignable.
950 if (elementclass->flags & ACC_INTERFACE) {
951 /* We are assigning to an interface type. */
953 return merged_implements_interface(value->elementclass.cls,
958 /* We are assigning to a class type. */
959 return class_issubclass(value->elementclass.cls,elementclass);
965 /* {dest.cls is not an array} */
966 /* {dest.cls is a loaded class} */
968 /* If there are any unresolved references in the merged list, we cannot */
969 /* tell if the assignment will be ok. */
970 /* This can only happen when cls is java.lang.Object */
971 if (cls == class_java_lang_Object && value->merged) {
972 classref_or_classinfo *mlist = value->merged->list;
973 int i = value->merged->count;
975 if (IS_CLASSREF(*mlist++))
979 /* We are assigning to a class type */
980 if (cls->flags & ACC_INTERFACE)
981 cls = class_java_lang_Object;
983 return class_issubclass(cls,dest.cls);
986 /**********************************************************************/
987 /* INITIALIZATION FUNCTIONS */
988 /* The following functions fill in uninitialized typeinfo structures. */
989 /**********************************************************************/
992 typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
998 TYPEINFO_ASSERT(c.any);
999 TYPEINFO_ASSERT(info);
1001 /* if necessary, try to resolve lazily */
1002 if (!resolve_classref_or_classinfo(NULL /* XXX should now method */,
1003 c,resolveLazy,false,true,&cls))
1009 TYPEINFO_INIT_CLASSINFO(*info,cls);
1013 /* {the type could no be resolved lazily} */
1015 info->typeclass.ref = c.ref;
1016 info->elementclass.any = NULL;
1017 info->dimension = 0;
1018 info->merged = NULL;
1020 /* handle array type references */
1021 utf_ptr = c.ref->name->text;
1022 len = c.ref->name->blength;
1023 if (*utf_ptr == '[') {
1024 /* count dimensions */
1025 while (*utf_ptr == '[') {
1030 if (*utf_ptr == 'L') {
1033 info->elementtype = ARRAYTYPE_OBJECT;
1034 info->elementclass.ref = class_get_classref(c.ref->referer,utf_new(utf_ptr,len));
1037 /* an array with primitive element type */
1038 /* should have been resolved above */
1039 TYPEINFO_ASSERT(false);
1046 typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
1048 TYPEINFO_ASSERT(desc);
1050 #ifdef TYPEINFO_VERBOSE
1051 fprintf(stderr,"typeinfo_init_from_typedesc(");
1052 descriptor_debug_print_typedesc(stderr,desc);
1053 fprintf(stderr,")\n");
1060 if (desc->type == TYPE_ADR) {
1061 TYPEINFO_ASSERT(desc->classref);
1062 if (!typeinfo_init_class(info,CLASSREF_OR_CLASSINFO(desc->classref)))
1066 TYPEINFO_INIT_PRIMITIVE(*info);
1073 typeinfo_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
1074 int buflen,bool twoword,
1075 u1 *returntype,typeinfo *returntypeinfo)
1080 TYPEINFO_ASSERT(desc);
1081 TYPEINFO_ASSERT(typebuf);
1082 TYPEINFO_ASSERT(infobuf);
1084 #ifdef TYPEINFO_VERBOSE
1085 fprintf(stderr,"typeinfo_init_from_methoddesc(");
1086 descriptor_debug_print_methoddesc(stderr,desc);
1087 fprintf(stderr,")\n");
1090 /* check arguments */
1091 for (i=0; i<desc->paramcount; ++i) {
1092 if (++args > buflen) {
1093 log_text("Buffer too small for method arguments."); /* XXX */
1097 if (!typeinfo_init_from_typedesc(desc->paramtypes + i,typebuf++,infobuf++))
1100 if (twoword && (typebuf[-1] == TYPE_LONG || typebuf[-1] == TYPE_DOUBLE)) {
1101 if (++args > buflen) {
1102 log_text("Buffer too small for method arguments."); /* XXX */
1106 *typebuf++ = TYPE_VOID;
1107 TYPEINFO_INIT_PRIMITIVE(*infobuf);
1112 /* check returntype */
1114 if (!typeinfo_init_from_typedesc(&(desc->returntype),returntype,returntypeinfo))
1122 typedescriptor_init_from_typedesc(typedescriptor *td,
1125 td->type = desc->type;
1126 if (td->type == TYPE_ADR) {
1127 if (!typeinfo_init_class(&(td->info),CLASSREF_OR_CLASSINFO(desc->classref)))
1131 TYPEINFO_INIT_PRIMITIVE(td->info);
1137 typedescriptors_init_from_methoddesc(typedescriptor *td,
1139 int buflen,bool twoword,int startindex,
1140 typedescriptor *returntype)
1145 /* check arguments */
1146 for (i=startindex; i<desc->paramcount; ++i) {
1147 if (++args > buflen) {
1148 log_text("Buffer too small for method arguments."); /* XXX */
1152 if (!typedescriptor_init_from_typedesc(td,desc->paramtypes + i))
1156 if (twoword && (td[-1].type == TYPE_LONG || td[-1].type == TYPE_DOUBLE)) {
1157 if (++args > buflen) {
1158 log_text("Buffer too small for method arguments."); /* XXX */
1162 td->type = TYPE_VOID;
1163 TYPEINFO_INIT_PRIMITIVE(td->info);
1168 /* check returntype */
1170 if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1178 typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
1180 if (TYPEINFO_IS_NULLTYPE(*srcarray)) {
1181 TYPEINFO_INIT_NULLTYPE(*dst);
1185 if (!TYPEINFO_IS_ARRAY(*srcarray)) {
1186 log_text("Trying to access component of non-array"); /* XXX throw exception */
1190 if (IS_CLASSREF(srcarray->typeclass)) {
1191 constant_classref *comp;
1192 comp = class_get_classref_component_of(srcarray->typeclass.ref);
1195 if (!typeinfo_init_class(dst,CLASSREF_OR_CLASSINFO(comp)))
1199 TYPEINFO_INIT_PRIMITIVE(*dst);
1205 if (!srcarray->typeclass.cls->linked) {
1206 if (!link_class(srcarray->typeclass.cls)) {
1211 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl);
1212 TYPEINFO_ASSERT(srcarray->typeclass.cls->vftbl->arraydesc);
1214 comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
1216 TYPEINFO_INIT_CLASSINFO(*dst,comp->class);
1218 TYPEINFO_INIT_PRIMITIVE(*dst);
1221 dst->merged = srcarray->merged; /* XXX should we do a deep copy? */
1226 typeinfo_clone(typeinfo *src,typeinfo *dest)
1229 classref_or_classinfo *srclist,*destlist;
1237 count = src->merged->count;
1238 TYPEINFO_ALLOCMERGED(dest->merged,count);
1239 dest->merged->count = count;
1241 srclist = src->merged->list;
1242 destlist = dest->merged->list;
1244 *destlist++ = *srclist++;
1248 /**********************************************************************/
1249 /* MISCELLANEOUS FUNCTIONS */
1250 /**********************************************************************/
1253 typeinfo_free(typeinfo *info)
1255 TYPEINFO_FREEMERGED_IF_ANY(info->merged);
1256 info->merged = NULL;
1259 /**********************************************************************/
1260 /* MERGING FUNCTIONS */
1261 /* The following functions are used to merge the types represented by */
1262 /* two typeinfo structures into one typeinfo structure. */
1263 /**********************************************************************/
1267 typeinfo_merge_error(char *str,typeinfo *x,typeinfo *y) {
1268 #ifdef TYPEINFO_VERBOSE
1269 fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
1270 fprintf(stderr,"Typeinfo x:\n");
1271 typeinfo_print(stderr,x,1);
1272 fprintf(stderr,"Typeinfo y:\n");
1273 typeinfo_print(stderr,y,1);
1276 log_text(str); /* XXX throw an exception */
1280 /* Condition: clsx != clsy. */
1281 /* Returns: true if dest was changed (currently always true). */
1284 typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
1286 TYPEINFO_ASSERT(dest);
1287 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1288 TYPEINFO_ALLOCMERGED(dest->merged,2);
1289 dest->merged->count = 2;
1291 TYPEINFO_ASSERT(clsx.any != clsy.any);
1293 if (clsx.any < clsy.any) {
1294 dest->merged->list[0] = clsx;
1295 dest->merged->list[1] = clsy;
1298 dest->merged->list[0] = clsy;
1299 dest->merged->list[1] = clsx;
1305 /* Returns: true if dest was changed. */
1308 typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo cls)
1311 typeinfo_mergedlist *newmerged;
1312 classref_or_classinfo *mlist,*newlist;
1317 /* Check if cls is already in the mergedlist m. */
1319 if ((mlist++)->any == cls.any) { /* XXX check equal classrefs? */
1320 /* cls is in the list, so m is the resulting mergedlist */
1321 if (dest->merged == m)
1324 /* We have to copy the mergedlist */
1325 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1327 TYPEINFO_ALLOCMERGED(dest->merged,count);
1328 dest->merged->count = count;
1329 newlist = dest->merged->list;
1332 *newlist++ = *mlist++;
1338 /* Add cls to the mergedlist. */
1340 TYPEINFO_ALLOCMERGED(newmerged,count+1);
1341 newmerged->count = count+1;
1342 newlist = newmerged->list;
1345 if (mlist->any > cls.any)
1347 *newlist++ = *mlist++;
1352 *newlist++ = *mlist++;
1355 /* Put the new mergedlist into dest. */
1356 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1357 dest->merged = newmerged;
1362 /* Returns: true if dest was changed. */
1365 typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
1366 typeinfo_mergedlist *y)
1370 typeinfo_mergedlist *temp,*result;
1371 classref_or_classinfo *clsx,*clsy,*newlist;
1373 /* count the elements that will be in the resulting list */
1374 /* (Both lists are sorted, equal elements are counted only once.) */
1379 while (countx && county) {
1380 if (clsx->any == clsy->any) {
1386 else if (clsx->any < clsy->any) {
1396 count += countx + county;
1398 /* {The new mergedlist will have count entries.} */
1400 if ((x->count != count) && (y->count == count)) {
1401 temp = x; x = y; y = temp;
1403 /* {If one of x,y is already the result it is x.} */
1404 if (x->count == count) {
1405 /* x->merged is equal to the result */
1406 if (x == dest->merged)
1409 if (!dest->merged || dest->merged->count != count) {
1410 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1411 TYPEINFO_ALLOCMERGED(dest->merged,count);
1412 dest->merged->count = count;
1415 newlist = dest->merged->list;
1418 *newlist++ = *clsx++;
1423 /* {We have to merge two lists.} */
1425 /* allocate the result list */
1426 TYPEINFO_ALLOCMERGED(result,count);
1427 result->count = count;
1428 newlist = result->list;
1430 /* merge the sorted lists */
1435 while (countx && county) {
1436 if (clsx->any == clsy->any) {
1437 *newlist++ = *clsx++;
1442 else if (clsx->any < clsy->any) {
1443 *newlist++ = *clsx++;
1447 *newlist++ = *clsy++;
1452 *newlist++ = *clsx++;
1454 *newlist++ = *clsy++;
1456 /* replace the list in dest with the result list */
1457 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1458 dest->merged = result;
1465 typeinfo_merge_nonarrays(typeinfo *dest,
1466 classref_or_classinfo *result,
1467 classref_or_classinfo x,classref_or_classinfo y,
1468 typeinfo_mergedlist *mergedx,
1469 typeinfo_mergedlist *mergedy)
1471 classref_or_classinfo t;
1472 classinfo *tcls,*common;
1473 typeinfo_mergedlist *tmerged;
1478 TYPEINFO_ASSERT(dest && result && x.any && y.any);
1479 TYPEINFO_ASSERT(x.cls != pseudo_class_Null);
1480 TYPEINFO_ASSERT(y.cls != pseudo_class_Null);
1481 TYPEINFO_ASSERT(x.cls != pseudo_class_New);
1482 TYPEINFO_ASSERT(y.cls != pseudo_class_New);
1484 /*--------------------------------------------------*/
1486 /*--------------------------------------------------*/
1488 /* Common case 1: x and y are the same class or class reference */
1489 /* (This case is very simple unless *both* x and y really represent
1490 * merges of subclasses of clsx==clsy.)
1492 if ( (x.any == y.any) && (!mergedx || !mergedy) ) {
1494 /* DEBUG */ /* log_text("return simple x"); */
1495 changed = (dest->merged != NULL);
1496 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1497 dest->merged = NULL;
1499 /* DEBUG */ /* log_text("returning"); */
1503 xname = (IS_CLASSREF(x)) ? x.ref->name : x.cls->name;
1504 yname = (IS_CLASSREF(y)) ? y.ref->name : y.cls->name;
1506 /* Common case 2: xname == yname, at least one unresolved */
1507 if ((IS_CLASSREF(x) || IS_CLASSREF(y)) && (xname == yname))
1509 /* use the loaded one if any */
1510 if (!IS_CLASSREF(y))
1512 goto return_simple_x;
1515 /*--------------------------------------------------*/
1516 /* non-trivial cases */
1517 /*--------------------------------------------------*/
1519 #ifdef TYPEINFO_VERBOSE
1522 fprintf(stderr,"merge_nonarrays:\n");
1523 fprintf(stderr," ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint(stderr,xname);fprintf(stderr,"\n");
1524 fprintf(stderr," ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint(stderr,yname);fprintf(stderr,"\n");
1526 TYPEINFO_INIT_CLASSREF_OR_CLASSINFO(dbgx,x);
1527 dbgx.merged = mergedx;
1528 TYPEINFO_INIT_CLASSREF_OR_CLASSINFO(dbgy,y);
1529 dbgy.merged = mergedy;
1530 typeinfo_print(stderr,&dbgx,4);
1531 fprintf(stderr," with:\n");
1532 typeinfo_print(stderr,&dbgy,4);
1536 TYPEINFO_ASSERT(IS_CLASSREF(x) || x.cls->loaded);
1537 TYPEINFO_ASSERT(IS_CLASSREF(y) || y.cls->loaded);
1539 /* If y is unresolved or an interface, swap x and y. */
1540 if (IS_CLASSREF(y) || (!IS_CLASSREF(x) && y.cls->flags & ACC_INTERFACE))
1542 t = x; x = y; y = t;
1543 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1546 /* {We know: If only one of x,y is unresolved it is x,} */
1547 /* { If both x,y are resolved and only one of x,y is an interface it is x.} */
1549 if (IS_CLASSREF(x)) {
1550 /* {We know: x and y have different class names} */
1552 /* Check if we are merging an unresolved type with java.lang.Object */
1553 if (y.cls == class_java_lang_Object && !mergedy) {
1555 goto return_simple_x;
1558 common = class_java_lang_Object;
1559 goto merge_with_simple_x;
1562 /* {We know: both x and y are resolved} */
1563 /* {We know: If only one of x,y is an interface it is x.} */
1565 TYPEINFO_ASSERT(!IS_CLASSREF(x) && !IS_CLASSREF(y));
1566 TYPEINFO_ASSERT(x.cls->loaded);
1567 TYPEINFO_ASSERT(y.cls->loaded);
1569 /* Handle merging of interfaces: */
1570 if (x.cls->flags & ACC_INTERFACE) {
1571 /* {x.cls is an interface and mergedx == NULL.} */
1573 if (y.cls->flags & ACC_INTERFACE) {
1574 /* We are merging two interfaces. */
1575 /* {mergedy == NULL} */
1577 /* {We know that x.cls!=y.cls (see common case at beginning.)} */
1578 result->cls = class_java_lang_Object;
1579 return typeinfo_merge_two(dest,x,y);
1582 /* {We know: x is an interface, y is a class.} */
1584 /* Check if we are merging an interface with java.lang.Object */
1585 if (y.cls == class_java_lang_Object && !mergedy) {
1587 goto return_simple_x;
1590 /* If the type y implements x then the result of the merge
1591 * is x regardless of mergedy.
1594 /* we may have to link the classes */
1596 link_class(x.cls); /* XXX */
1598 link_class(y.cls); /* XXX */
1600 TYPEINFO_ASSERT(x.cls->linked);
1601 TYPEINFO_ASSERT(y.cls->linked);
1603 if (CLASSINFO_IMPLEMENTS_INTERFACE(y.cls,x.cls->index)
1604 || mergedlist_implements_interface(mergedy,x.cls))
1606 /* y implements x, so the result of the merge is x. */
1607 goto return_simple_x;
1610 /* {We know: x is an interface, the type y a class or a merge
1611 * of subclasses and does not implement x.} */
1613 /* There may still be superinterfaces of x which are implemented
1614 * by y, too, so we have to add x.cls to the mergedlist.
1617 /* if x has no superinterfaces we could return a simple java.lang.Object */
1619 common = class_java_lang_Object;
1620 goto merge_with_simple_x;
1623 /* {We know: x and y are classes (not interfaces).} */
1625 /* we may have to link the classes */
1627 link_class(x.cls); /* XXX */
1629 link_class(y.cls); /* XXX */
1631 TYPEINFO_ASSERT(x.cls->linked);
1632 TYPEINFO_ASSERT(y.cls->linked);
1634 /* If *x is deeper in the inheritance hierarchy swap x and y. */
1635 if (x.cls->index > y.cls->index) {
1636 t = x; x = y; y = t;
1637 tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1640 /* {We know: y is at least as deep in the hierarchy as x.} */
1642 /* Find nearest common anchestor for the classes. */
1645 while (tcls->index > common->index)
1646 tcls = tcls->super.cls;
1647 while (common != tcls) {
1648 common = common->super.cls;
1649 tcls = tcls->super.cls;
1652 /* {common == nearest common anchestor of x and y.} */
1654 /* If x.cls==common and x is a whole class (not a merge of subclasses)
1655 * then the result of the merge is x.
1657 if (x.cls == common && !mergedx) {
1658 goto return_simple_x;
1662 result->cls = common;
1664 return typeinfo_merge_mergedlists(dest,mergedx,mergedy);
1666 return typeinfo_merge_add(dest,mergedx,y);
1669 merge_with_simple_x:
1670 result->cls = common;
1672 return typeinfo_merge_add(dest,mergedy,x);
1674 return typeinfo_merge_two(dest,x,y);
1677 /* Condition: *dest must be a valid initialized typeinfo. */
1678 /* Condition: dest != y. */
1679 /* Returns: true if dest was changed. */
1681 typeinfo_merge(typeinfo *dest,typeinfo* y)
1685 classref_or_classinfo common;
1686 classref_or_classinfo elementclass;
1691 /*--------------------------------------------------*/
1693 /*--------------------------------------------------*/
1695 /* Merging something with itself is a nop */
1699 /* Merging two returnAddress types is ok. */
1700 /* Merging two different returnAddresses never happens, as the verifier */
1701 /* keeps them separate in order to check all the possible return paths */
1702 /* from JSR subroutines. */
1703 if (!dest->typeclass.any && !y->typeclass.any) {
1704 TYPEINFO_ASSERT(TYPEINFO_RETURNADDRESS(*dest) == TYPEINFO_RETURNADDRESS(*y));
1708 /* Primitive types cannot be merged with reference types */
1709 /* XXX only check this in debug mode? */
1710 if (!dest->typeclass.any || !y->typeclass.any)
1711 typeinfo_merge_error("Trying to merge primitive types.",dest,y);
1713 /* handle uninitialized object types */
1714 if (TYPEINFO_IS_NEWOBJECT(*dest) || TYPEINFO_IS_NEWOBJECT(*y)) {
1715 if (!TYPEINFO_IS_NEWOBJECT(*dest) || !TYPEINFO_IS_NEWOBJECT(*y))
1716 typeinfo_merge_error("Trying to merge uninitialized object type.",dest,y);
1717 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*dest)
1718 != TYPEINFO_NEWOBJECT_INSTRUCTION(*y))
1719 typeinfo_merge_error("Trying to merge different uninitialized objects.",dest,y);
1723 /*--------------------------------------------------*/
1725 /*--------------------------------------------------*/
1727 /* Common case: dest and y are the same class or class reference */
1728 /* (This case is very simple unless *both* dest and y really represent
1729 * merges of subclasses of class dest==class y.)
1731 if ((dest->typeclass.any == y->typeclass.any) && (!dest->merged || !y->merged)) {
1733 changed = (dest->merged != NULL);
1734 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1735 dest->merged = NULL;
1739 /* Handle null types: */
1740 if (TYPEINFO_IS_NULLTYPE(*y)) {
1743 if (TYPEINFO_IS_NULLTYPE(*dest)) {
1744 TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1745 TYPEINFO_CLONE(*y,*dest);
1749 /* Common case: two types with the same name, at least one unresolved */
1750 if (IS_CLASSREF(dest->typeclass)) {
1751 if (IS_CLASSREF(y->typeclass)) {
1752 if (dest->typeclass.ref->name == y->typeclass.ref->name)
1756 /* XXX should we take y instead of dest here? */
1757 if (dest->typeclass.ref->name == y->typeclass.cls->name)
1762 if (IS_CLASSREF(y->typeclass)
1763 && (dest->typeclass.cls->name == y->typeclass.ref->name))
1769 /*--------------------------------------------------*/
1770 /* non-trivial cases */
1771 /*--------------------------------------------------*/
1773 #ifdef TYPEINFO_VERBOSE
1774 fprintf(stderr,"merge:\n");
1775 typeinfo_print(stderr,dest,4);
1776 typeinfo_print(stderr,y,4);
1779 /* This function uses x internally, so x and y can be swapped
1780 * without changing dest. */
1784 /* Handle merging of arrays: */
1785 if (TYPEINFO_IS_ARRAY(*x) && TYPEINFO_IS_ARRAY(*y)) {
1787 /* Make x the one with lesser dimension */
1788 if (x->dimension > y->dimension) {
1789 tmp = x; x = y; y = tmp;
1792 /* If one array (y) has higher dimension than the other,
1793 * interpret it as an array (same dim. as x) of Arraystubs. */
1794 if (x->dimension < y->dimension) {
1795 dimension = x->dimension;
1796 elementtype = ARRAYTYPE_OBJECT;
1797 elementclass.cls = pseudo_class_Arraystub;
1800 dimension = y->dimension;
1801 elementtype = y->elementtype;
1802 elementclass = y->elementclass;
1805 /* {The arrays are of the same dimension.} */
1807 if (x->elementtype != elementtype) {
1808 /* Different element types are merged, so the resulting array
1809 * type has one accessible dimension less. */
1810 if (--dimension == 0) {
1811 common.cls = pseudo_class_Arraystub;
1813 elementclass.any = NULL;
1816 common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub,true);
1818 log_text("XXX Coult not create array class");
1822 elementtype = ARRAYTYPE_OBJECT;
1823 elementclass.cls = pseudo_class_Arraystub;
1827 /* {The arrays have the same dimension and elementtype.} */
1829 if (elementtype == ARRAYTYPE_OBJECT) {
1830 /* The elements are references, so their respective
1831 * types must be merged.
1833 changed |= typeinfo_merge_nonarrays(dest,
1837 x->merged,y->merged);
1839 /* DEBUG */ /* log_text("finding resulting array class: "); */
1840 if (IS_CLASSREF(elementclass))
1841 common.ref = class_get_classref_multiarray_of(dimension,elementclass.ref);
1843 common.cls = class_multiarray_of(dimension,elementclass.cls,true);
1845 log_text("XXX Coult not create array class");
1849 /* DEBUG */ /* utf_display(common->name); printf("\n"); */
1852 common.any = y->typeclass.any;
1857 /* {We know that at least one of x or y is no array, so the
1858 * result cannot be an array.} */
1860 changed |= typeinfo_merge_nonarrays(dest,
1862 x->typeclass,y->typeclass,
1863 x->merged,y->merged);
1867 elementclass.any = NULL;
1870 /* Put the new values into dest if neccessary. */
1872 if (dest->typeclass.any != common.any) {
1873 dest->typeclass.any = common.any;
1876 if (dest->dimension != dimension) {
1877 dest->dimension = dimension;
1880 if (dest->elementtype != elementtype) {
1881 dest->elementtype = elementtype;
1884 if (dest->elementclass.any != elementclass.any) {
1885 dest->elementclass.any = elementclass.any;
1893 /**********************************************************************/
1894 /* DEBUGGING HELPERS */
1895 /**********************************************************************/
1897 #ifdef TYPEINFO_DEBUG
1901 typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
1903 if (a->any == b->any) return 0;
1904 if (a->any < b->any) return -1;
1909 typeinfo_test_parse(typeinfo *info,char *str)
1916 utf *desc = utf_new_char(str);
1918 num = typeinfo_count_method_args(desc,false);
1920 typebuf = DMNEW(u1,num);
1921 infobuf = DMNEW(typeinfo,num);
1923 typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
1926 TYPEINFO_ALLOCMERGED(info->merged,num);
1927 info->merged->count = num;
1929 for (i=0; i<num; ++i) {
1930 if (typebuf[i] != TYPE_ADDRESS) {
1931 log_text("non-reference type in mergedlist");
1935 info->merged->list[i].any = infobuf[i].typeclass.any;
1937 qsort(info->merged->list,num,sizeof(classref_or_classinfo),
1938 (int(*)(const void *,const void *))&typeinfo_test_compare);
1941 typeinfo_init_from_method_args(desc,NULL,NULL,0,false,
1947 #define TYPEINFO_TEST_BUFLEN 4000
1950 typeinfo_equal(typeinfo *x,typeinfo *y)
1954 if (x->typeclass.any != y->typeclass.any) return false;
1955 if (x->dimension != y->dimension) return false;
1957 if (x->elementclass.any != y->elementclass.any) return false;
1958 if (x->elementtype != y->elementtype) return false;
1961 if (TYPEINFO_IS_NEWOBJECT(*x))
1962 if (TYPEINFO_NEWOBJECT_INSTRUCTION(*x)
1963 != TYPEINFO_NEWOBJECT_INSTRUCTION(*y))
1966 if (x->merged || y->merged) {
1967 if (!(x->merged && y->merged)) return false;
1968 if (x->merged->count != y->merged->count) return false;
1969 for (i=0; i<x->merged->count; ++i)
1970 if (x->merged->list[i].any != y->merged->list[i].any)
1977 typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
1980 bool changed,changed_should_be;
1982 TYPEINFO_CLONE(*a,dest);
1985 typeinfo_print_short(stdout,&dest);
1987 typeinfo_print_short(stdout,b);
1990 changed = (typeinfo_merge(&dest,b)) ? 1 : 0;
1991 changed_should_be = (!typeinfo_equal(&dest,a)) ? 1 : 0;
1993 printf(" %s\n",(changed) ? "changed" : "=");
1995 if (typeinfo_equal(&dest,result)) {
1997 typeinfo_print_short(stdout,&dest);
1999 if (changed != changed_should_be) {
2000 printf("WRONG RETURN VALUE!\n");
2006 typeinfo_print_short(stdout,&dest);
2008 printf("SHOULD BE ");
2009 typeinfo_print_short(stdout,result);
2017 typeinfo_inc_dimension(typeinfo *info)
2019 if (info->dimension++ == 0) {
2020 info->elementtype = ARRAYTYPE_OBJECT;
2021 info->elementclass = info->typeclass;
2023 info->typeclass = class_array_of(info->typeclass,true);
2027 #define TYPEINFO_TEST_MAXDIM 10
2030 typeinfo_testrun(char *filename)
2032 char buf[TYPEINFO_TEST_BUFLEN];
2033 char bufa[TYPEINFO_TEST_BUFLEN];
2034 char bufb[TYPEINFO_TEST_BUFLEN];
2035 char bufc[TYPEINFO_TEST_BUFLEN];
2039 FILE *file = fopen(filename,"rt");
2043 log_text("could not open typeinfo test file");
2047 while (fgets(buf,TYPEINFO_TEST_BUFLEN,file)) {
2048 if (buf[0] == '#' || !strlen(buf))
2051 res = sscanf(buf,"%s\t%s\t%s\n",bufa,bufb,bufc);
2052 if (res != 3 || !strlen(bufa) || !strlen(bufb) || !strlen(bufc)) {
2053 log_text("Invalid line in typeinfo test file (none of empty, comment or test)");
2058 typeinfo_test_parse(&a,bufa);
2059 typeinfo_test_parse(&b,bufb);
2060 typeinfo_test_parse(&c,bufc);
2065 typeinfo_testmerge(&a,&b,&c,&failed); /* check result */
2066 typeinfo_testmerge(&b,&a,&c,&failed); /* check commutativity */
2068 if (TYPEINFO_IS_NULLTYPE(a)) break;
2069 if (TYPEINFO_IS_NULLTYPE(b)) break;
2070 if (TYPEINFO_IS_NULLTYPE(c)) break;
2072 maxdim = a.dimension;
2073 if (b.dimension > maxdim) maxdim = b.dimension;
2074 if (c.dimension > maxdim) maxdim = c.dimension;
2077 if (maxdim < TYPEINFO_TEST_MAXDIM) {
2078 typeinfo_inc_dimension(&a);
2079 typeinfo_inc_dimension(&b);
2080 typeinfo_inc_dimension(&c);
2082 } while (maxdim < TYPEINFO_TEST_MAXDIM);
2089 fprintf(stderr,"Failed typeinfo_merge tests: %d\n",failed);
2090 log_text("Failed test");
2098 log_text("Running typeinfo test file...");
2099 typeinfo_testrun("typeinfo.tst");
2100 log_text("Finished typeinfo test file.");
2105 typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc)
2107 typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
2111 #define TYPEINFO_MAXINDENT 80
2114 typeinfo_print_class(FILE *file,classref_or_classinfo c)
2116 /*fprintf(file,"<class %p>",c.any);*/
2119 fprintf(file,"<null>");
2122 if (IS_CLASSREF(c)) {
2123 fprintf(file,"<ref>");
2124 utf_fprint(file,c.ref->name);
2127 utf_fprint(file,c.cls->name);
2133 typeinfo_print(FILE *file,typeinfo *info,int indent)
2136 char ind[TYPEINFO_MAXINDENT + 1];
2140 if (indent > TYPEINFO_MAXINDENT) indent = TYPEINFO_MAXINDENT;
2142 for (i=0; i<indent; ++i)
2146 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2147 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2149 fprintf(file,"%sreturnAddress (L%03d)\n",ind,bptr->debug_nr);
2151 fprintf(file,"%sprimitive\n",ind);
2155 if (TYPEINFO_IS_NULLTYPE(*info)) {
2156 fprintf(file,"%snull\n",ind);
2160 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2161 ins = (instruction *)TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2163 fprintf(file,"%sNEW(%p):",ind,(void*)ins);
2164 typeinfo_print_class(file,CLASSREF_OR_CLASSINFO(ins[-1].val.a));
2168 fprintf(file,"%sNEW(this)",ind);
2173 fprintf(file,"%sClass: ",ind);
2174 typeinfo_print_class(file,info->typeclass);
2177 if (TYPEINFO_IS_ARRAY(*info)) {
2178 fprintf(file,"%sDimension: %d",ind,(int)info->dimension);
2179 fprintf(file,"\n%sElements: ",ind);
2180 switch (info->elementtype) {
2181 case ARRAYTYPE_INT : fprintf(file,"int\n"); break;
2182 case ARRAYTYPE_LONG : fprintf(file,"long\n"); break;
2183 case ARRAYTYPE_FLOAT : fprintf(file,"float\n"); break;
2184 case ARRAYTYPE_DOUBLE : fprintf(file,"double\n"); break;
2185 case ARRAYTYPE_BYTE : fprintf(file,"byte\n"); break;
2186 case ARRAYTYPE_CHAR : fprintf(file,"char\n"); break;
2187 case ARRAYTYPE_SHORT : fprintf(file,"short\n"); break;
2188 case ARRAYTYPE_BOOLEAN : fprintf(file,"boolean\n"); break;
2190 case ARRAYTYPE_OBJECT:
2191 typeinfo_print_class(file,info->elementclass);
2196 fprintf(file,"INVALID ARRAYTYPE!\n");
2201 fprintf(file,"%sMerged: ",ind);
2202 for (i=0; i<info->merged->count; ++i) {
2203 if (i) fprintf(file,", ");
2204 typeinfo_print_class(file,info->merged->list[i]);
2211 typeinfo_print_short(FILE *file,typeinfo *info)
2217 /*fprintf(file,"<typeinfo %p>",info);*/
2220 fprintf(file,"(typeinfo*)NULL");
2224 if (TYPEINFO_IS_PRIMITIVE(*info)) {
2225 bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
2227 fprintf(file,"ret(L%03d)",bptr->debug_nr);
2229 fprintf(file,"primitive");
2233 if (TYPEINFO_IS_NULLTYPE(*info)) {
2234 fprintf(file,"null");
2238 if (TYPEINFO_IS_NEWOBJECT(*info)) {
2239 ins = (instruction *)TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
2241 /*fprintf(file,"<ins %p>",ins);*/
2242 fprintf(file,"NEW(%p):",(void*)ins);
2243 typeinfo_print_class(file,CLASSREF_OR_CLASSINFO(ins[-1].val.a));
2246 fprintf(file,"NEW(this)");
2250 typeinfo_print_class(file,info->typeclass);
2254 for (i=0; i<info->merged->count; ++i) {
2255 if (i) fprintf(file,",");
2256 typeinfo_print_class(file,info->merged->list[i]);
2263 typeinfo_print_type(FILE *file,int type,typeinfo *info)
2266 case TYPE_VOID: fprintf(file,"V"); break;
2267 case TYPE_INT: fprintf(file,"I"); break;
2268 case TYPE_FLOAT: fprintf(file,"F"); break;
2269 case TYPE_DOUBLE: fprintf(file,"D"); break;
2270 case TYPE_LONG: fprintf(file,"J"); break;
2272 typeinfo_print_short(file,info);
2281 typeinfo_print_stacktype(FILE *file,int type,typeinfo *info)
2283 TYPEINFO_ASSERT(file);
2284 TYPEINFO_ASSERT(type != TYPE_ADDRESS || info != NULL);
2285 if (type == TYPE_ADDRESS && TYPEINFO_IS_PRIMITIVE(*info)) {
2286 typeinfo_retaddr_set *set = (typeinfo_retaddr_set*)
2287 TYPEINFO_RETURNADDRESS(*info);
2289 fprintf(file,"ret(L%03d",((basicblock*)(set->addr))->debug_nr);
2292 fprintf(file,"|L%03d",((basicblock*)(set->addr))->debug_nr);
2297 fprintf(file,"ret(<NULL>");
2302 typeinfo_print_type(file,type,info);
2306 typedescriptor_print(FILE *file,typedescriptor *td)
2308 typeinfo_print_type(file,td->type,&(td->info));
2312 typevector_print(FILE *file,typevector *vec,int size)
2316 fprintf(file,"[%d]",vec->k);
2317 for (i=0; i<size; ++i) {
2318 fprintf(file," %d=",i);
2319 typedescriptor_print(file,vec->td + i);
2324 typevectorset_print(FILE *file,typevector *set,int size)
2329 fprintf(file,"[%d",set->k);
2332 fprintf(file,"|%d",vec->k);
2337 for (i=0; i<size; ++i) {
2338 fprintf(file," %d=",i);
2339 typedescriptor_print(file,set->td + i);
2343 typedescriptor_print(file,vec->td + i);
2349 #endif /* TYPEINFO_DEBUG */
2353 * These are local overrides for various environment variables in Emacs.
2354 * Please do not remove this and leave it at the end of the file, where
2355 * Emacs will automagically detect them.
2356 * ---------------------------------------------------------------------
2359 * indent-tabs-mode: t