CACAO
typeinfo.cpp
Go to the documentation of this file.
1 /* src/vm/jit/verify/typeinfo.cpp - type system used by the type checker
2 
3  Copyright (C) 1996-2014
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
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.
12 
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.
17 
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
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <assert.h>
29 #include <string.h>
30 
31 #include "mm/dumpmemory.hpp"
32 
33 #include "toolbox/logging.hpp"
34 
35 #include "vm/array.hpp"
36 #include "vm/class.hpp"
37 #include "vm/descriptor.hpp"
38 #include "vm/exceptions.hpp"
39 #include "vm/globals.hpp"
40 #include "vm/primitive.hpp"
41 #include "vm/resolve.hpp"
42 
43 #include "vm/jit/jit.hpp"
45 
47 
48 
49 /* check if a linked class is an array class. Only use for linked classes! */
50 #define CLASSINFO_IS_ARRAY(clsinfo) ((clsinfo)->vftbl->arraydesc != NULL)
51 
52 /* check if a linked class implements the interface with the given index */
53 #define CLASSINFO_IMPLEMENTS_INTERFACE(cls,index) \
54  ( ((index) < (cls)->vftbl->interfacetablelength) \
55  && ( (cls)->vftbl->interfacetable[-(index)] != NULL ) )
56 
57 /******************************************************************************/
58 /* DEBUG HELPERS */
59 /******************************************************************************/
60 
61 #ifdef TYPEINFO_DEBUG
62 #define TYPEINFO_ASSERT(cond) assert(cond)
63 #else
64 #define TYPEINFO_ASSERT(cond)
65 #endif
66 
67 /**********************************************************************/
68 /* TYPEVECTOR FUNCTIONS */
69 /**********************************************************************/
70 
71 #if defined(ENABLE_VERIFIER)
72 
73 /* typevector_copy *************************************************************
74 
75  Return a copy of the given typevector.
76 
77  IN:
78  src..............typevector set to copy, must be != NULL
79  size.............number of elements per typevector
80 
81  RETURN VALUE:
82  a pointer to the new typevector set
83 
84 *******************************************************************************/
85 
86 varinfo *
88 {
89  varinfo *dst;
90 
91  TYPEINFO_ASSERT(src);
92 
93  dst = DNEW_TYPEVECTOR(size);
94  memcpy(dst,src,TYPEVECTOR_SIZE(size));
95 
96  return dst;
97 }
98 
99 /* typevector_copy_inplace *****************************************************
100 
101  Copy a typevector to a given destination.
102 
103  IN:
104  src..............typevector to copy, must be != NULL
105  dst..............destination to write the copy to
106  size.............number of elements per typevector
107 
108 *******************************************************************************/
109 
110 void
112 {
113  memcpy(dst,src,TYPEVECTOR_SIZE(size));
114 }
115 
116 /* typevector_checktype ********************************************************
117 
118  Check if the typevector contains a given type at a given index.
119 
120  IN:
121  vec..............typevector set, must be != NULL
122  index............index of component to check
123  type.............TYPE_* constant to check against
124 
125  RETURN VALUE:
126  true if the typevector contains TYPE at INDEX,
127  false otherwise
128 
129 *******************************************************************************/
130 
131 bool
133 {
134  TYPEINFO_ASSERT(vec);
135 
136  return vec[index].type == type;
137 }
138 
139 /* typevector_checkreference ***************************************************
140 
141  Check if the typevector contains a reference at a given index.
142 
143  IN:
144  vec..............typevector, must be != NULL
145  index............index of component to check
146 
147  RETURN VALUE:
148  true if the typevector contains a reference at INDEX,
149  false otherwise
150 
151 *******************************************************************************/
152 
153 bool
155 {
156  TYPEINFO_ASSERT(vec);
157  return vec[index].is_reference();
158 }
159 
160 /* typevectorset_checkretaddr **************************************************
161 
162  Check if the typevectors contains a returnAddress at a given index.
163 
164  IN:
165  vec..............typevector, must be != NULL
166  index............index of component to check
167 
168  RETURN VALUE:
169  true if the typevector contains a returnAddress at INDEX,
170  false otherwise
171 
172 *******************************************************************************/
173 
174 bool
176 {
177  TYPEINFO_ASSERT(vec);
178  return vec[index].is_returnaddress();
179 }
180 
181 /* typevector_store ************************************************************
182 
183  Store a type at a given index in the typevector.
184 
185  IN:
186  vec..............typevector set, must be != NULL
187  index............index of component to set
188  type.............TYPE_* constant of type to set
189  info.............typeinfo of type to set, may be NULL,
190  if TYPE != TYPE_ADR
191 
192 *******************************************************************************/
193 
194 void
196 {
197  TYPEINFO_ASSERT(vec);
198 
199  vec[index].type = type;
200  if (info)
201  vec[index].typeinfo = *info;
202 }
203 
204 /* typevector_store_retaddr ****************************************************
205 
206  Store a returnAddress type at a given index in the typevector.
207 
208  IN:
209  vec..............typevector set, must be != NULL
210  index............index of component to set
211  info.............typeinfo of the returnAddress.
212 
213 *******************************************************************************/
214 
215 void
217 {
218  TYPEINFO_ASSERT(vec);
219  TYPEINFO_ASSERT(info->is_primitive());
220 
221  vec[index].type = TYPE_ADR;
223 }
224 
225 /* typevector_init_object ******************************************************
226 
227  Replace all uninitialized object types in the typevector set which were
228  created by the given instruction by initialized object types.
229 
230  IN:
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
235 
236  RETURN VALUE:
237  true.............success
238  false............an exception has been thrown
239 
240  XXX maybe we should do the lazy resolving before calling this function
241 
242 *******************************************************************************/
243 
244 bool
246  classref_or_classinfo initclass,
247  int size)
248 {
249  int i;
250 
251  for (i=0; i<size; ++i) {
252  if (set[i].type == TYPE_ADR
253  && set[i].typeinfo.is_newobject()
254  && set[i].typeinfo.newobject_instruction() == ins)
255  {
256  if (!set[i].typeinfo.init_class(initclass))
257  return false;
258  }
259  }
260  return true;
261 }
262 
263 /* typevector_merge ************************************************************
264 
265  Merge a typevector with another one.
266  The given typevectors must have the same number of components.
267 
268  IN:
269  m................method for exception messages
270  dst..............the first typevector
271  y................the second typevector
272  size.............number of elements per typevector
273 
274  OUT:
275  *dst.............the resulting typevector
276 
277  RETURN VALUE:
278  typecheck_TRUE...dst has been modified
279  typecheck_FALSE..dst has not been modified
280  typecheck_FAIL...an exception has been thrown
281 
282 *******************************************************************************/
283 
286 {
287  bool changed = false;
289 
290  varinfo *a = dst;
291  varinfo *b = y;
292  while (size--) {
293  if (a->type != TYPE_VOID && a->type != b->type) {
294  a->type = TYPE_VOID;
295  changed = true;
296  }
297  else if (a->type == TYPE_ADR) {
298  if (a->typeinfo.is_primitive()) {
299  /* 'a' is a returnAddress */
300  if (!b->typeinfo.is_primitive()
301  || (a->typeinfo.returnaddress() != b->typeinfo.returnaddress()))
302  {
303  a->type = TYPE_VOID;
304  changed = true;
305  }
306  }
307  else {
308  /* 'a' is a reference */
309  if (b->typeinfo.is_primitive()) {
310  a->type = TYPE_VOID;
311  changed = true;
312  }
313  else {
314  /* two reference types are merged. There cannot be */
315  /* a merge error. In the worst case we get j.l.O. */
316  r = a->typeinfo.merge(m, &(b->typeinfo));
317  if (r == typecheck_FAIL)
318  return r;
319  changed |= r;
320  }
321  }
322  }
323  a++;
324  b++;
325  }
326  return (typecheck_result) changed;
327 }
328 
329 /**********************************************************************/
330 /* READ-ONLY FUNCTIONS */
331 /* The following functions don't change typeinfo data. */
332 /**********************************************************************/
333 
334 /* interface_extends_interface *************************************************
335 
336  Check if a resolved interface extends a given resolved interface.
337 
338  IN:
339  cls..............the interface, must be linked
340  interf...........the interface to check against
341 
342  RETURN VALUE:
343  true.............CLS extends INTERF
344  false............CLS does not extend INTERF
345 
346 *******************************************************************************/
347 
348 static bool
350 {
351  int i;
352 
353  TYPEINFO_ASSERT(cls);
354  TYPEINFO_ASSERT(interf);
355  TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
356  TYPEINFO_ASSERT((cls->flags & ACC_INTERFACE) != 0);
358 
359  /* first check direct superinterfaces */
360  for (i=0; i<cls->interfacescount; ++i) {
361  if (cls->interfaces[i] == interf)
362  return true;
363  }
364 
365  /* check indirect superinterfaces */
366  for (i=0; i<cls->interfacescount; ++i) {
367  if (interface_extends_interface(cls->interfaces[i],interf))
368  return true;
369  }
370 
371  return false;
372 }
373 
374 /* classinfo_implements_interface **********************************************
375 
376  Check if a resolved class implements a given resolved interface.
377 
378  IN:
379  cls..............the class
380  interf...........the interface
381 
382  RETURN VALUE:
383  typecheck_TRUE...CLS implements INTERF
384  typecheck_FALSE..CLS does not implement INTERF
385  typecheck_FAIL...an exception has been thrown
386 
387 *******************************************************************************/
388 
389 static typecheck_result
391 {
392  TYPEINFO_ASSERT(cls);
393  TYPEINFO_ASSERT(interf);
394  TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
395 
396  if (!(cls->state & CLASS_LINKED))
397  if (!link_class(cls))
398  return typecheck_FAIL;
399 
400  if (cls->flags & ACC_INTERFACE) {
401  /* cls is an interface */
402  if (cls == interf)
403  return typecheck_TRUE;
404 
405  /* check superinterfaces */
406  return (typecheck_result) interface_extends_interface(cls,interf);
407  }
408 
411 }
412 
413 /* mergedlist_implements_interface *********************************************
414 
415  Check if all the classes in a given merged list implement a given resolved
416  interface.
417 
418  IN:
419  merged...........the list of merged class types
420  interf...........the interface to check against
421 
422  RETURN VALUE:
423  typecheck_TRUE...all classes implement INTERF
424  typecheck_FALSE..there is at least one class that does not implement
425  INTERF
426  typecheck_MAYBE..check cannot be performed now because of unresolved
427  classes
428  typecheck_FAIL...an exception has been thrown
429 
430 *******************************************************************************/
431 
432 static typecheck_result
434  classinfo *interf)
435 {
436  int i;
437  classref_or_classinfo *mlist;
439 
440  TYPEINFO_ASSERT(interf);
441  TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
442 
443  /* Check if there is an non-empty mergedlist. */
444  if (!merged)
445  return typecheck_FALSE;
446 
447  /* If all classinfos in the (non-empty) merged array implement the
448  * interface return true, otherwise false.
449  */
450  mlist = merged->list;
451  i = merged->count;
452  while (i--) {
453  if (mlist->is_classref()) {
454  return typecheck_MAYBE;
455  }
456  r = classinfo_implements_interface((mlist++)->cls,interf);
457  if (r != typecheck_TRUE)
458  return r;
459  }
460  return typecheck_TRUE;
461 }
462 
463 /* merged_implements_interface *************************************************
464 
465  Check if a possible merged type implements a given resolved interface
466  interface.
467 
468  IN:
469  typeclass........(common) class of the (merged) type
470  merged...........the list of merged class types
471  interf...........the interface to check against
472 
473  RETURN VALUE:
474  typecheck_TRUE...the type implement INTERF
475  typecheck_FALSE..the type does not implement INTERF
476  typecheck_MAYBE..check cannot be performed now because of unresolved
477  classes
478  typecheck_FAIL...an exception has been thrown
479 
480 *******************************************************************************/
481 
482 static typecheck_result
484  classinfo *interf)
485 {
487 
488  /* primitive types don't support interfaces. */
489  if (!typeclass)
490  return typecheck_FALSE;
491 
492  /* the null type can be cast to any interface type. */
493  if (typeclass == pseudo_class_Null)
494  return typecheck_TRUE;
495 
496  /* check if typeclass implements the interface. */
497  r = classinfo_implements_interface(typeclass,interf);
498  if (r != typecheck_FALSE)
499  return r;
500 
501  /* check the mergedlist */
502  if (!merged)
503  return typecheck_FALSE;
504  return mergedlist_implements_interface(merged,interf);
505 }
506 
507 /* merged_is_subclass **********************************************************
508 
509  Check if a possible merged type is a subclass of a given class.
510  A merged type is a subclass of a class C if all types in the merged list
511  are subclasses of C. A sufficient condition for this is that the
512  common type of the merged type is a subclass of C.
513 
514  IN:
515  typeclass........(common) class of the (merged) type
516  MUST be a loaded and linked class
517  merged...........the list of merged class types
518  cls..............the class to theck against
519 
520  RETURN VALUE:
521  typecheck_TRUE...the type is a subclass of CLS
522  typecheck_FALSE..the type is not a subclass of CLS
523  typecheck_MAYBE..check cannot be performed now because of unresolved
524  classes
525  typecheck_FAIL...an exception has been thrown
526 
527 *******************************************************************************/
528 
529 static typecheck_result
531  classinfo *cls)
532 {
533  int i;
534  classref_or_classinfo *mlist;
535 
536  TYPEINFO_ASSERT(cls);
537 
538  /* primitive types aren't subclasses of anything. */
539  if (!typeclass)
540  return typecheck_FALSE;
541 
542  /* the null type can be cast to any reference type. */
543  if (typeclass == pseudo_class_Null)
544  return typecheck_TRUE;
545 
546  TYPEINFO_ASSERT(typeclass->state & CLASS_LOADED);
547  TYPEINFO_ASSERT(typeclass->state & CLASS_LINKED);
548 
549  /* check if the common typeclass is a subclass of CLS. */
550  if (class_issubclass(typeclass,cls))
551  return typecheck_TRUE;
552 
553  /* check the mergedlist */
554  if (!merged)
555  return typecheck_FALSE;
556  /* If all classinfos in the (non-empty) merged list are subclasses
557  * of CLS, return true, otherwise false.
558  * If there is at least one unresolved type in the list,
559  * return typecheck_MAYBE.
560  */
561  mlist = merged->list;
562  i = merged->count;
563  while (i--) {
564  if (mlist->is_classref()) {
565  return typecheck_MAYBE;
566  }
567  if (!(mlist->cls->state & CLASS_LINKED))
568  if (!link_class(mlist->cls))
569  return typecheck_FAIL;
570  if (!class_issubclass(mlist->cls,cls))
571  return typecheck_FALSE;
572  mlist++;
573  }
574  return typecheck_TRUE;
575 }
576 
577 /***
578  * Check if a type is assignable to a given class type.
579  *
580  * RETURN VALUE:
581  * typecheck_TRUE...the type is assignable
582  * typecheck_FALSE..the type is not assignable
583  * typecheck_MAYBE..check cannot be performed now because of unresolved classes
584  * typecheck_FAIL...an exception has been thrown
585  */
588 
589  /* assignments of primitive values are not checked here. */
590  if (!c.any && !dest.any)
591  return typecheck_TRUE;
592 
593  /* primitive and reference types are not assignment compatible. */
594  if (!c.any || !dest.any)
595  return typecheck_FALSE;
596 
597  /* the null type can be assigned to any type */
598  if (is_nulltype())
599  return typecheck_TRUE;
600 
601  /* uninitialized objects are not assignable */
602  if (is_newobject())
603  return typecheck_FALSE;
604 
605  Utf8String classname = CLASSREF_OR_CLASSINFO_NAME(c);
606 
607  if (dest.is_classref()) {
608  /* the destination type is an unresolved class reference */
609  /* In this case we cannot tell a lot about assignability. */
610 
611  /* the common case of value and dest type having the same classname */
612  if (dest.ref->name == classname && !merged)
613  return typecheck_TRUE;
614 
615  /* we cannot tell if value is assignable to dest, so we */
616  /* leave it up to the resolving code to check this */
617  return typecheck_MAYBE;
618  }
619 
620  /* { we know that dest is a loaded class } */
621 
622  if (c.is_classref()) {
623  /* the value type is an unresolved class reference */
624 
625  /* the common case of value and dest type having the same classname */
626  if (dest.cls->name == classname)
627  return typecheck_TRUE;
628 
629  /* we cannot tell if value is assignable to dest, so we */
630  /* leave it up to the resolving code to check this */
631  return typecheck_MAYBE;
632  }
633 
634  /* { we know that both c and dest are loaded classes } */
635  /* (c may still have a merged list containing unresolved classrefs!) */
636 
639 
640  classinfo *cls = c.cls;
641 
642  TYPEINFO_ASSERT(cls->state & CLASS_LOADED);
644 
645  /* maybe we need to link the classes */
646  if (!(cls->state & CLASS_LINKED))
647  if (!link_class(cls))
648  return typecheck_FAIL;
649  if (!(dest.cls->state & CLASS_LINKED))
650  if (!link_class(dest.cls))
651  return typecheck_FAIL;
652 
653  /* { we know that both c and dest are linked classes } */
654  TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
656 
657  if (dest.cls->flags & ACC_INTERFACE) {
658  /* We are assigning to an interface type. */
659  return merged_implements_interface(cls, merged, dest.cls);
660  }
661 
662  if (CLASSINFO_IS_ARRAY(dest.cls)) {
663  arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
664  int dimension = arraydesc->dimension;
665  classinfo *elementclass = (arraydesc->elementvftbl) ? arraydesc->elementvftbl->clazz : NULL;
666 
667  /* We are assigning to an array type. */
668  if (!is_array())
669  return typecheck_FALSE;
670 
671  /* {Both value and dest.cls are array types.} */
672 
673  /* value must have at least the dimension of dest.cls. */
674  if (this->dimension < dimension)
675  return typecheck_FALSE;
676 
677  if (this->dimension > dimension) {
678  /* value has higher dimension so we need to check
679  * if its component array can be assigned to the
680  * element type of dest.cls */
681 
682  if (!elementclass) return typecheck_FALSE;
683 
684  if (elementclass->flags & ACC_INTERFACE) {
685  /* We are assigning to an interface type. */
687  }
688 
689  /* We are assigning to a class type. */
691  }
692 
693  /* {value and dest.cls have the same dimension} */
694 
695  if (elementtype != arraydesc->elementtype)
696  return typecheck_FALSE;
697 
698  if (this->elementclass.any) {
699  /* We are assigning an array of objects so we have to
700  * check if the elements are assignable.
701  */
702 
703  if (elementclass->flags & ACC_INTERFACE) {
704  /* We are assigning to an interface type. */
705 
706  return merged_implements_interface(this->elementclass.cls, merged, elementclass);
707  }
708 
709  /* We are assigning to a class type. */
710  return merged_is_subclass(this->elementclass.cls, merged, elementclass);
711  }
712 
713  return typecheck_TRUE;
714  }
715 
716  /* {dest.cls is not an array} */
717  /* {dest.cls is a loaded class} */
718 
719  /* If there are any unresolved references in the merged list, we cannot */
720  /* tell if the assignment will be ok. */
721  /* This can only happen when cls is java.lang.Object */
722  if (cls == class_java_lang_Object && merged) {
724  int i = merged->count;
725  while (i--) {
726  if (mlist->is_classref())
727  return typecheck_MAYBE;
728  mlist++;
729  }
730  }
731 
732  /* We are assigning to a class type */
733  if (cls->flags & ACC_INTERFACE)
735 
736  return merged_is_subclass(cls, merged, dest.cls);
737 }
738 
739 /***
740  *
741  * Check if a type is assignable to a given type.
742  *
743  * @param dest the type of the destination, must not be a merged type
744  *
745  * RETURN VALUE:
746  * typecheck_TRUE...the type is assignable
747  * typecheck_FALSE..the type is not assignable
748  * typecheck_MAYBE..check cannot be performed now because of unresolved classes
749  * typecheck_FAIL...an exception has been thrown
750  */
752  TYPEINFO_ASSERT(dest);
753  TYPEINFO_ASSERT(dest->merged == NULL);
754 
755  return is_assignable_to_class(dest->typeclass);
756 }
757 
758 /**********************************************************************/
759 /* INITIALIZATION FUNCTIONS */
760 /* The following functions fill in uninitialized typeinfo structures. */
761 /**********************************************************************/
762 
763 /* internally used macros ***************************************************/
764 
765 #define TYPEINFO_ALLOCMERGED(mergedlist,count) \
766  do {(mergedlist) = (typeinfo_mergedlist_t *) DumpMemory::allocate(sizeof(typeinfo_mergedlist_t) \
767  + ((count)-1)*sizeof(classinfo*));} while(0)
768 
769 #define TYPEINFO_FREEMERGED(mergedlist)
770 
771 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
772 
773 
774 /* typeinfo_t::init_class ******************************************************
775 
776  Initialize a typeinfo to a resolved class.
777 
778  IN:
779  c................the class
780 
781  OUT:
782  *info............is initialized
783 
784  RETURN VALUE:
785  true.............success
786  false............an exception has been thrown
787 
788 *******************************************************************************/
789 
791  if ((typeclass.cls = c)->vftbl->arraydesc) {
792  if (c->vftbl->arraydesc->elementvftbl)
794  else
795  elementclass.any = NULL;
798  }
799  else {
800  elementclass.any = NULL;
801  dimension = 0;
803  }
804  merged = NULL;
805 }
806 
807 /* typeinfo_t::init_class ******************************************************
808 
809  Initialize a typeinfo to a possibly unresolved class type.
810 
811  IN:
812  c................the class type
813 
814  OUT:
815  *info............is initialized
816 
817  RETURN VALUE:
818  true.............success
819  false............an exception has been thrown
820 
821 *******************************************************************************/
822 
824  TYPEINFO_ASSERT(c.any);
825 
826  classinfo *cls;
827 
828  /* if necessary, try to resolve lazily */
829  if (!resolve_classref_or_classinfo(NULL /* XXX should know method */,
830  c,resolveLazy,false,true,&cls))
831  {
832  return false;
833  }
834 
835  if (cls) {
836  init_class(cls);
837  return true;
838  }
839 
840  /* {the type could no be resolved lazily} */
841 
842  typeclass.ref = c.ref;
843  elementclass.any = NULL;
844  dimension = 0;
845  merged = NULL;
846 
847  /* handle array type references */
848  const char *utf_ptr = c.ref->name.begin();
849  int len = c.ref->name.size();
850  if (*utf_ptr == '[') {
851  /* count dimensions */
852  while (*utf_ptr == '[') {
853  utf_ptr++;
854  dimension++;
855  len--;
856  }
857  if (*utf_ptr == 'L') {
858  utf_ptr++;
859  len -= 2;
862  }
863  else {
864  /* an array with primitive element type */
865  /* should have been resolved above */
866  TYPEINFO_ASSERT(false);
867  }
868  }
869  return true;
870 }
871 
872 /* typeinfo_t::init_from_typedesc **********************************************
873 
874  Initialize a typeinfo from a typedesc.
875 
876  IN:
877  desc.............the typedesc
878 
879  OUT:
880  *type............set to the TYPE_* constant of DESC (if type != NULL)
881  *info............receives the typeinfo (if info != NULL)
882 
883  RETURN VALUE:
884  true.............success
885  false............an exception has been thrown
886 
887 *******************************************************************************/
888 
889 bool typeinfo_t::init_from_typedesc(const typedesc *desc, u1 *type) {
890 #ifdef TYPEINFO_VERBOSE
891  fprintf(stderr,"typeinfo_init_from_typedesc(");
892  descriptor_debug_print_typedesc(stderr,this);
893  fprintf(stderr,")\n");
894 #endif
895 
896  if (type)
897  *type = desc->type;
898 
899  if (desc->type == TYPE_ADR) {
900  TYPEINFO_ASSERT(desc->classref);
901  if (!init_class(desc->classref))
902  return false;
903  }
904  else {
905  init_primitive();
906  }
907  return true;
908 }
909 
910 
911 /* typedescriptor_init_from_typedesc *******************************************
912 
913  Initialize a typedescriptor from a typedesc.
914 
915  IN:
916  desc.............the typedesc
917 
918  OUT:
919  *td..............receives the typedescriptor
920  td must be != NULL
921 
922  RETURN VALUE:
923  true.............success
924  false............an exception has been thrown
925 
926 *******************************************************************************/
927 
929  TYPEINFO_ASSERT(td);
930  TYPEINFO_ASSERT(desc);
931 
932  td->type = desc->type;
933  if (td->type == TYPE_ADR) {
934  if (!td->typeinfo.init_class(desc->classref))
935  return false;
936  }
937  else {
938  td->typeinfo.init_primitive();
939  }
940  return true;
941 }
942 
943 /* typeinfo_init_varinfo_from_typedesc *****************************************
944 
945  Initialize a varinfo from a typedesc.
946 
947  IN:
948  desc.............the typedesc
949 
950  OUT:
951  *var.............receives the type
952  var must be != NULL
953 
954  RETURN VALUE:
955  true.............success
956  false............an exception has been thrown
957 
958 *******************************************************************************/
959 
961  TYPEINFO_ASSERT(var);
962  TYPEINFO_ASSERT(desc);
963 
964  var->type = desc->type;
965  if (var->type == TYPE_ADR) {
966  if (!var->typeinfo.init_class(desc->classref))
967  return false;
968  }
969  else {
970  var->typeinfo.init_primitive();
971  }
972  return true;
973 }
974 
975 /* typeinfo_init_varinfos_from_methoddesc **************************************
976 
977  Initialize an array of varinfos from a methoddesc.
978 
979  IN:
980  desc.............the methoddesc
981  buflen...........number of parameters the buffer can hold
982  startindex.......the zero-based index of the first parameter to
983  write to the array. In other words the number of
984  parameters to skip at the beginning of the methoddesc.
985  map..............map from parameter indices to varinfo indices
986  (indexed like jitdata.local_map)
987 
988  OUT:
989  *vars............array receiving the varinfos
990  td[0] receives the type of the
991  (startindex+1)th parameter of the method
992  *returntype......receives the typedescriptor of the return type.
993  returntype may be NULL
994 
995  RETURN VALUE:
996  true.............everything ok
997  false............an exception has been thrown
998 
999  NOTE:
1000  If (according to BUFLEN) the buffer is to small to hold the
1001  parameter types, an internal error is thrown. This must be
1002  avoided by checking the number of parameters and allocating enough
1003  space before calling this function.
1004 
1005 *******************************************************************************/
1006 
1007 bool
1009  methoddesc *desc,
1010  int buflen, int startindex,
1011  s4 *map,
1012  typedescriptor_t *returntype)
1013 {
1014  s4 i;
1015  s4 varindex;
1016  s4 type;
1017  s4 slot = 0;
1018 
1019  /* skip arguments */
1020  for (i=0; i<startindex; ++i) {
1021  slot++;
1022  if (IS_2_WORD_TYPE(desc->paramtypes[i].type))
1023  slot++;
1024  }
1025 
1026  /* check arguments */
1027  for (i=startindex; i<desc->paramcount; ++i) {
1028  type = desc->paramtypes[i].type;
1029  varindex = map[5*slot + type];
1030 
1031  slot++;
1032  if (IS_2_WORD_TYPE(type))
1033  slot++;
1034 
1035  if (varindex == jitdata::UNUSED)
1036  continue;
1037 
1038  if (varindex >= buflen) {
1039  exceptions_throw_internalerror("Buffer too small for method arguments.");
1040  return false;
1041  }
1042 
1043  if (!typeinfo_init_varinfo_from_typedesc(vars + varindex, desc->paramtypes + i))
1044  return false;
1045  }
1046 
1047  /* check returntype */
1048  if (returntype) {
1049  if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1050  return false;
1051  }
1052 
1053  return true;
1054 }
1055 
1056 /* typedescriptors_init_from_methoddesc ****************************************
1057 
1058  Initialize an array of typedescriptors from a methoddesc.
1059 
1060  IN:
1061  desc.............the methoddesc
1062  buflen...........number of parameters the buffer can hold
1063  twoword..........if true, use two parameter slots for two-word types
1064  startindex.......the zero-based index of the first parameter to
1065  write to the array. In other words the number of
1066  parameters to skip at the beginning of the methoddesc.
1067 
1068  OUT:
1069  *td..............array receiving the typedescriptors.
1070  td[0] receives the typedescriptor of the
1071  (startindex+1)th parameter of the method
1072  *returntype......receives the typedescriptor of the return type.
1073  returntype may be NULL
1074 
1075  RETURN VALUE:
1076  >= 0.............number of typedescriptors filled in TD
1077  -1...............an exception has been thrown
1078 
1079  NOTE:
1080  If (according to BUFLEN) the buffer is to small to hold the
1081  parameter types, an internal error is thrown. This must be
1082  avoided by checking the number of parameters and allocating enough
1083  space before calling this function.
1084 
1085 *******************************************************************************/
1086 
1087 int
1089  methoddesc *desc,
1090  int buflen,bool twoword,int startindex,
1091  typedescriptor_t *returntype)
1092 {
1093  int i;
1094  int args = 0;
1095 
1096  /* check arguments */
1097  for (i=startindex; i<desc->paramcount; ++i) {
1098  if (++args > buflen) {
1099  exceptions_throw_internalerror("Buffer too small for method arguments.");
1100  return -1;
1101  }
1102 
1103  if (!typedescriptor_init_from_typedesc(td,desc->paramtypes + i))
1104  return -1;
1105  td++;
1106 
1107  if (twoword && (td[-1].type == TYPE_LNG || td[-1].type == TYPE_DBL)) {
1108  if (++args > buflen) {
1109  exceptions_throw_internalerror("Buffer too small for method arguments.");
1110  return -1;
1111  }
1112 
1113  td->type = TYPE_VOID;
1114  td->typeinfo.init_primitive();
1115  td++;
1116  }
1117  }
1118 
1119  /* check returntype */
1120  if (returntype) {
1121  if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
1122  return -1;
1123  }
1124 
1125  return args;
1126 }
1127 
1128 /* typeinfo_t::init_component ***************************************************
1129 
1130  Initialize a typeinfo with the component type of a given array type.
1131 
1132  IN:
1133  srcarray.........the typeinfo of the array type
1134 
1135  OUT:
1136  *dst.............receives the typeinfo of the component type
1137 
1138  RETURN VALUE:
1139  true.............success
1140  false............an exception has been thrown
1141 
1142 *******************************************************************************/
1143 
1145  if (srcarray.is_nulltype()) {
1146  init_nulltype();
1147  return true;
1148  }
1149 
1150  if (!srcarray.is_array()) {
1151  /* XXX should we make that a verify error? */
1152  exceptions_throw_internalerror("Trying to access component of non-array");
1153  return false;
1154  }
1155 
1156  /* save the mergedlist (maybe this == srcarray) */
1157 
1158  typeinfo_mergedlist_t *merged = srcarray.merged;
1159 
1160  if (srcarray.typeclass.is_classref()) {
1162 
1163  if (comp) {
1164  if (!init_class(comp))
1165  return false;
1166  }
1167  else {
1168  init_primitive();
1169  }
1170  }
1171  else {
1172  if (!(srcarray.typeclass.cls->state & CLASS_LINKED)) {
1173  if (!link_class(srcarray.typeclass.cls)) {
1174  return false;
1175  }
1176  }
1177 
1178  TYPEINFO_ASSERT(srcarray.typeclass.cls->vftbl);
1180 
1181  if (vftbl_t *comp = srcarray.typeclass.cls->vftbl->arraydesc->componentvftbl)
1182  init_class(comp->clazz);
1183  else
1184  init_primitive();
1185  }
1186 
1187  this->merged = merged; /* XXX should we do a deep copy? */
1188  return true;
1189 }
1190 
1191 /***
1192  * Create a deep copy of the `merged' list of a typeinfo
1193  */
1195  int count = src.merged->count;
1196  TYPEINFO_ALLOCMERGED(dst.merged,count);
1197  dst.merged->count = count;
1198 
1199  classref_or_classinfo *srclist = src.merged->list;
1200  classref_or_classinfo *dstlist = dst.merged->list;
1201 
1202  while (count--)
1203  *dstlist++ = *srclist++;
1204 }
1205 
1206 
1207 /**********************************************************************/
1208 /* MISCELLANEOUS FUNCTIONS */
1209 /**********************************************************************/
1210 
1211 /**********************************************************************/
1212 /* MERGING FUNCTIONS */
1213 /* The following functions are used to merge the types represented by */
1214 /* two typeinfo structures into one typeinfo structure. */
1215 /**********************************************************************/
1216 
1217 static void typeinfo_merge_error(methodinfo *m, const char *str, const typeinfo_t *x, const typeinfo_t *y) {
1218 #ifdef TYPEINFO_VERBOSE
1219  fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
1220  fprintf(stderr,"Typeinfo x:\n");
1221  typeinfo_print(stderr,x,1);
1222  fprintf(stderr,"Typeinfo y:\n");
1223  typeinfo_print(stderr,y,1);
1224  log_text(str);
1225 #endif
1226 
1228 }
1229 
1230 /* Condition: clsx != clsy. */
1231 /* Returns: true if dest was changed (currently always true). */
1232 static
1233 bool
1235 {
1236  TYPEINFO_ASSERT(dest);
1238  TYPEINFO_ALLOCMERGED(dest->merged,2);
1239  dest->merged->count = 2;
1240 
1241  TYPEINFO_ASSERT(clsx.any != clsy.any);
1242 
1243  if (clsx.any < clsy.any) {
1244  dest->merged->list[0] = clsx;
1245  dest->merged->list[1] = clsy;
1246  }
1247  else {
1248  dest->merged->list[0] = clsy;
1249  dest->merged->list[1] = clsx;
1250  }
1251 
1252  return true;
1253 }
1254 
1255 /* Returns: true if dest was changed. */
1256 static
1257 bool
1259 {
1260  int count;
1261  typeinfo_mergedlist_t *newmerged;
1262  classref_or_classinfo *mlist,*newlist;
1263 
1264  count = m->count;
1265  mlist = m->list;
1266 
1267  /* Check if cls is already in the mergedlist m. */
1268  while (count--) {
1269  if ((mlist++)->any == cls.any) { /* XXX check equal classrefs? */
1270  /* cls is in the list, so m is the resulting mergedlist */
1271  if (dest->merged == m)
1272  return false;
1273 
1274  /* We have to copy the mergedlist */
1276  count = m->count;
1277  TYPEINFO_ALLOCMERGED(dest->merged,count);
1278  dest->merged->count = count;
1279  newlist = dest->merged->list;
1280  mlist = m->list;
1281  while (count--) {
1282  *newlist++ = *mlist++;
1283  }
1284  return true;
1285  }
1286  }
1287 
1288  /* Add cls to the mergedlist. */
1289  count = m->count;
1290  TYPEINFO_ALLOCMERGED(newmerged,count+1);
1291  newmerged->count = count+1;
1292  newlist = newmerged->list;
1293  mlist = m->list;
1294  while (count) {
1295  if (mlist->any > cls.any)
1296  break;
1297  *newlist++ = *mlist++;
1298  count--;
1299  }
1300  *newlist++ = cls;
1301  while (count--) {
1302  *newlist++ = *mlist++;
1303  }
1304 
1305  /* Put the new mergedlist into dest. */
1307  dest->merged = newmerged;
1308 
1309  return true;
1310 }
1311 
1312 /* Returns: true if dest was changed. */
1313 static
1314 bool
1317 {
1318  int count = 0;
1319  int countx,county;
1320  typeinfo_mergedlist_t *temp,*result;
1321  classref_or_classinfo *clsx,*clsy,*newlist;
1322 
1323  /* count the elements that will be in the resulting list */
1324  /* (Both lists are sorted, equal elements are counted only once.) */
1325  clsx = x->list;
1326  clsy = y->list;
1327  countx = x->count;
1328  county = y->count;
1329  while (countx && county) {
1330  if (clsx->any == clsy->any) {
1331  clsx++;
1332  clsy++;
1333  countx--;
1334  county--;
1335  }
1336  else if (clsx->any < clsy->any) {
1337  clsx++;
1338  countx--;
1339  }
1340  else {
1341  clsy++;
1342  county--;
1343  }
1344  count++;
1345  }
1346  count += countx + county;
1347 
1348  /* {The new mergedlist will have count entries.} */
1349 
1350  if ((x->count != count) && (y->count == count)) {
1351  temp = x; x = y; y = temp;
1352  }
1353  /* {If one of x,y is already the result it is x.} */
1354  if (x->count == count) {
1355  /* x->merged is equal to the result */
1356  if (x == dest->merged)
1357  return false;
1358 
1359  if (!dest->merged || dest->merged->count != count) {
1361  TYPEINFO_ALLOCMERGED(dest->merged,count);
1362  dest->merged->count = count;
1363  }
1364 
1365  newlist = dest->merged->list;
1366  clsx = x->list;
1367  while (count--) {
1368  *newlist++ = *clsx++;
1369  }
1370  return true;
1371  }
1372 
1373  /* {We have to merge two lists.} */
1374 
1375  /* allocate the result list */
1376  TYPEINFO_ALLOCMERGED(result,count);
1377  result->count = count;
1378  newlist = result->list;
1379 
1380  /* merge the sorted lists */
1381  clsx = x->list;
1382  clsy = y->list;
1383  countx = x->count;
1384  county = y->count;
1385  while (countx && county) {
1386  if (clsx->any == clsy->any) {
1387  *newlist++ = *clsx++;
1388  clsy++;
1389  countx--;
1390  county--;
1391  }
1392  else if (clsx->any < clsy->any) {
1393  *newlist++ = *clsx++;
1394  countx--;
1395  }
1396  else {
1397  *newlist++ = *clsy++;
1398  county--;
1399  }
1400  }
1401  while (countx--)
1402  *newlist++ = *clsx++;
1403  while (county--)
1404  *newlist++ = *clsy++;
1405 
1406  /* replace the list in dest with the result list */
1408  dest->merged = result;
1409 
1410  return true;
1411 }
1412 
1413 /* typeinfo_merge_nonarrays ****************************************************
1414 
1415  Merge two non-array types.
1416 
1417  IN:
1418  x................the first type
1419  y................the second type
1420  mergedx..........merged list of the first type, may be NULL
1421  mergedy..........merged list of the descond type, may be NULL
1422 
1423  OUT:
1424  *dest............receives the resulting merged list
1425  *result..........receives the resulting type
1426 
1427  RETURN VALUE:
1428  typecheck_TRUE...*dest has been modified
1429  typecheck_FALSE..*dest has not been modified
1430  typecheck_FAIL...an exception has been thrown
1431 
1432  NOTE:
1433  RESULT is an extra parameter so it can point to dest->typeclass or to
1434  dest->elementclass.
1435 
1436 *******************************************************************************/
1437 
1438 static typecheck_result
1440  classref_or_classinfo *result,
1442  typeinfo_mergedlist_t *mergedx,
1443  typeinfo_mergedlist_t *mergedy)
1444 {
1445  classinfo *tcls,*common;
1446  bool changed;
1447  typecheck_result r;
1448 
1449  TYPEINFO_ASSERT(dest && result && x.any && y.any);
1454 
1455  /*--------------------------------------------------*/
1456  /* common cases */
1457  /*--------------------------------------------------*/
1458 
1459  /* Common case 1: x and y are the same class or class reference */
1460  /* (This case is very simple unless *both* x and y really represent
1461  * merges of subclasses of clsx==clsy.)
1462  */
1463  if ( (x.any == y.any) && (!mergedx || !mergedy) ) {
1464  return_simple_x:
1465  /* DEBUG */ /* log_text("return simple x"); */
1466  changed = (dest->merged != NULL);
1468  dest->merged = NULL;
1469  *result = x;
1470  /* DEBUG */ /* log_text("returning"); */
1471  return (typecheck_result) changed;
1472  }
1473 
1476 
1477  /* Common case 2: xname == yname, at least one unresolved */
1478  if ((xname == yname) && (x.is_classref() || y.is_classref()))
1479  {
1480  /* use the loaded one if any */
1481  if (y.is_classinfo())
1482  x = y;
1483  goto return_simple_x;
1484  }
1485 
1486  /*--------------------------------------------------*/
1487  /* non-trivial cases */
1488  /*--------------------------------------------------*/
1489 
1490 #ifdef TYPEINFO_VERBOSE
1491  {
1492  typeinfo_t dbgx,dbgy;
1493  fprintf(stderr,"merge_nonarrays:\n");
1494  fprintf(stderr," ");if(x.is_classref())fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,xname);fprintf(stderr,"\n");
1495  fprintf(stderr," ");if(y.is_classref())fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,yname);fprintf(stderr,"\n");
1496  fflush(stderr);
1497  dbgx.init_class(x);
1498  dbgx.merged = mergedx;
1499  dbgy.init_class(y);
1500  dbgy.merged = mergedy;
1501  typeinfo_print(stderr,&dbgx,4);
1502  fprintf(stderr," with:\n");
1503  typeinfo_print(stderr,&dbgy,4);
1504  }
1505 #endif
1506 
1509 
1510  /* If y is unresolved or an interface, swap x and y. */
1511  if (y.is_classref() || (x.is_classinfo() && y.cls->flags & ACC_INTERFACE)) {
1512  classref_or_classinfo tmp = x; x = y; y = tmp;
1513  typeinfo_mergedlist_t *tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1514  }
1515 
1516  /* {We know: If only one of x,y is unresolved it is x,} */
1517  /* { If both x,y are resolved and only one of x,y is an interface it is x.} */
1518 
1519  if (x.is_classref()) {
1520  /* {We know: x and y have different class names} */
1521 
1522  /* Check if we are merging an unresolved type with java.lang.Object */
1523  if (y.cls == class_java_lang_Object && !mergedy) {
1524  x = y;
1525  goto return_simple_x;
1526  }
1527 
1528  common = class_java_lang_Object;
1529  goto merge_with_simple_x;
1530  }
1531 
1532  /* {We know: both x and y are resolved} */
1533  /* {We know: If only one of x,y is an interface it is x.} */
1534 
1538 
1539  /* Handle merging of interfaces: */
1540  if (x.cls->flags & ACC_INTERFACE) {
1541  /* {x.cls is an interface and mergedx == NULL.} */
1542 
1543  if (y.cls->flags & ACC_INTERFACE) {
1544  /* We are merging two interfaces. */
1545  /* {mergedy == NULL} */
1546 
1547  /* {We know that x.cls!=y.cls (see common case at beginning.)} */
1548  result->cls = class_java_lang_Object;
1549  return (typecheck_result) typeinfo_merge_two(dest,x,y);
1550  }
1551 
1552  /* {We know: x is an interface, y is a class.} */
1553 
1554  /* Check if we are merging an interface with java.lang.Object */
1555  if (y.cls == class_java_lang_Object && !mergedy) {
1556  x = y;
1557  goto return_simple_x;
1558  }
1559 
1560  /* If the type y implements x then the result of the merge
1561  * is x regardless of mergedy.
1562  */
1563 
1564  /* we may have to link the classes */
1565  if (!(x.cls->state & CLASS_LINKED))
1566  if (!link_class(x.cls))
1567  return typecheck_FAIL;
1568  if (!(y.cls->state & CLASS_LINKED))
1569  if (!link_class(y.cls))
1570  return typecheck_FAIL;
1571 
1574 
1576  {
1577  /* y implements x, so the result of the merge is x. */
1578  goto return_simple_x;
1579  }
1580 
1581  r = mergedlist_implements_interface(mergedy,x.cls);
1582  if (r == typecheck_FAIL)
1583  return r;
1584  if (r == typecheck_TRUE)
1585  {
1586  /* y implements x, so the result of the merge is x. */
1587  goto return_simple_x;
1588  }
1589 
1590  /* {We know: x is an interface, the type y a class or a merge
1591  * of subclasses and is not guaranteed to implement x.} */
1592 
1593  common = class_java_lang_Object;
1594  goto merge_with_simple_x;
1595  }
1596 
1597  /* {We know: x and y are classes (not interfaces).} */
1598 
1599  /* we may have to link the classes */
1600  if (!(x.cls->state & CLASS_LINKED))
1601  if (!link_class(x.cls))
1602  return typecheck_FAIL;
1603  if (!(y.cls->state & CLASS_LINKED))
1604  if (!link_class(y.cls))
1605  return typecheck_FAIL;
1606 
1609 
1610  /* If *x is deeper in the inheritance hierarchy swap x and y. */
1611  if (x.cls->index > y.cls->index) {
1612  classref_or_classinfo tmp = x; x = y; y = tmp;
1613  typeinfo_mergedlist_t *tmerged = mergedx; mergedx = mergedy; mergedy = tmerged;
1614  }
1615 
1616  /* {We know: y is at least as deep in the hierarchy as x.} */
1617 
1618  /* Find nearest common anchestor for the classes. */
1619 
1620  common = x.cls;
1621  tcls = y.cls;
1622 
1623  while (tcls->index > common->index)
1624  tcls = tcls->super;
1625 
1626  while (common != tcls) {
1627  common = common->super;
1628  tcls = tcls->super;
1629  }
1630 
1631  /* {common == nearest common anchestor of x and y.} */
1632 
1633  /* If x.cls==common and x is a whole class (not a merge of subclasses)
1634  * then the result of the merge is x.
1635  */
1636  if (x.cls == common && !mergedx) {
1637  goto return_simple_x;
1638  }
1639 
1640  if (mergedx) {
1641  result->cls = common;
1642  if (mergedy)
1643  return (typecheck_result) typeinfo_merge_mergedlists(dest,mergedx,mergedy);
1644  else
1645  return (typecheck_result) typeinfo_merge_add(dest,mergedx,y);
1646  }
1647 
1648 merge_with_simple_x:
1649  result->cls = common;
1650  if (mergedy)
1651  return (typecheck_result) typeinfo_merge_add(dest,mergedy,x);
1652  else
1653  return (typecheck_result) typeinfo_merge_two(dest,x,y);
1654 }
1655 
1656 /***
1657  *
1658  * Merge two types, stores result of merge in `this'.
1659  *
1660  * @param m method for exception messages
1661  * @param t the second type
1662  *
1663  * RETURN VALUE:
1664  * typecheck_TRUE...*dest has been modified
1665  * typecheck_FALSE..*dest has not been modified
1666  * typecheck_FAIL...an exception has been thrown
1667  *
1668  * @pre
1669  * 1) *dest must be a valid initialized typeinfo
1670  * 2) dest != y
1671  */
1673  const typeinfo_t *x;
1674  classref_or_classinfo common;
1676  int dimension;
1677  ArrayType new_elementtype;
1678  bool changed;
1679  typecheck_result r;
1680 
1681  /*--------------------------------------------------*/
1682  /* fast checks */
1683  /*--------------------------------------------------*/
1684 
1685  /* Merging something with itself is a nop */
1686  if (this == src)
1687  return typecheck_FALSE;
1688 
1689  /* Merging two returnAddress types is ok. */
1690  /* Merging two different returnAddresses never happens, as the verifier */
1691  /* keeps them separate in order to check all the possible return paths */
1692  /* from JSR subroutines. */
1693  if (!typeclass.any && !src->typeclass.any) {
1695  return typecheck_FALSE;
1696  }
1697 
1698  /* Primitive types cannot be merged with reference types */
1699  /* This must be checked before calls to typeinfo_merge. */
1700  TYPEINFO_ASSERT(this->typeclass.any && src->typeclass.any);
1701 
1702  /* handle uninitialized object types */
1703  if (is_newobject() || src->is_newobject()) {
1704  if (!is_newobject() || !src->is_newobject()) {
1705  typeinfo_merge_error(m,(char*) "Trying to merge uninitialized object type.", this, src);
1706  return typecheck_FAIL;
1707  }
1708  if (newobject_instruction() != src->newobject_instruction()) {
1709  typeinfo_merge_error(m,(char*) "Trying to merge different uninitialized objects.", this, src);
1710  return typecheck_FAIL;
1711  }
1712  /* the same uninitialized object -- no change */
1713  return typecheck_FALSE;
1714  }
1715 
1716  /*--------------------------------------------------*/
1717  /* common cases */
1718  /*--------------------------------------------------*/
1719 
1720  /* Common case: dest and y are the same class or class reference */
1721  /* (This case is very simple unless *both* dest and y really represent
1722  * merges of subclasses of class dest==class y.)
1723  */
1724  if ((this->typeclass.any == src->typeclass.any) && (!this->merged || !src->merged)) {
1725 return_simple:
1726  changed = (merged != NULL);
1728  merged = NULL;
1729  return (typecheck_result) changed;
1730  }
1731 
1732  /* Handle null types: */
1733  if (src->is_nulltype()) {
1734  return typecheck_FALSE;
1735  }
1736  if (is_nulltype()) {
1737  TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
1738  typeinfo_t::clone(*src, *this);
1739  return typecheck_TRUE;
1740  }
1741 
1742  /* Common case: two types with the same name, at least one unresolved */
1743  if (typeclass.is_classref()) {
1744  if (src->typeclass.is_classref()) {
1745  if (typeclass.ref->name == src->typeclass.ref->name)
1746  goto return_simple;
1747  }
1748  else {
1749  /* XXX should we take y instead of dest here? */
1750  if (typeclass.ref->name == src->typeclass.cls->name)
1751  goto return_simple;
1752  }
1753  }
1754  else {
1755  if (src->typeclass.is_classref() && (typeclass.cls->name == src->typeclass.ref->name))
1756  {
1757  goto return_simple;
1758  }
1759  }
1760 
1761  /*--------------------------------------------------*/
1762  /* non-trivial cases */
1763  /*--------------------------------------------------*/
1764 
1765 #ifdef TYPEINFO_VERBOSE
1766  fprintf(stderr,"merge:\n");
1767  typeinfo_print(stderr,dest,4);
1768  typeinfo_print(stderr,y,4);
1769 #endif
1770 
1771  /* This function uses x internally, so x and y can be swapped
1772  * without changing dest. */
1773  x = this;
1774  changed = false;
1775 
1776  /* Handle merging of arrays: */
1777  if (x->is_array() && src->is_array()) {
1778 
1779  /* Make x the one with lesser dimension */
1780  if (x->dimension > src->dimension) {
1781  const typeinfo_t *tmp = x; x = src; src = tmp;
1782  }
1783 
1784  /* If one array (y) has higher dimension than the other,
1785  * interpret it as an array (same dim. as x) of Arraystubs. */
1786  if (x->dimension < src->dimension) {
1787  dimension = x->dimension;
1788  new_elementtype = ARRAYTYPE_OBJECT;
1789  elementclass.cls = pseudo_class_Arraystub;
1790  }
1791  else {
1792  dimension = src->dimension;
1793  new_elementtype = src->elementtype;
1794  elementclass = src->elementclass;
1795  }
1796 
1797  /* {The arrays are of the same dimension.} */
1798 
1799  if (x->elementtype != new_elementtype) {
1800  /* Different element types are merged, so the resulting array
1801  * type has one accessible dimension less. */
1802  if (--dimension == 0) {
1803  common.cls = pseudo_class_Arraystub;
1804  new_elementtype = ARRAYTYPE_INT;
1805  elementclass.any = NULL;
1806  }
1807  else {
1808  common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub,true);
1809  if (!common.cls) {
1810  exceptions_throw_internalerror("XXX Coult not create array class");
1811  return typecheck_FAIL;
1812  }
1813 
1814  new_elementtype = ARRAYTYPE_OBJECT;
1815  elementclass.cls = pseudo_class_Arraystub;
1816  }
1817  }
1818  else {
1819  /* {The arrays have the same dimension and elementtype.} */
1820 
1821  if (new_elementtype == ARRAYTYPE_OBJECT) {
1822  /* The elements are references, so their respective
1823  * types must be merged.
1824  */
1825  r = typeinfo_merge_nonarrays(this,
1826  &elementclass,
1827  x->elementclass,
1828  elementclass,
1829  x->merged, src->merged);
1831  if (r == typecheck_FAIL)
1832  return r;
1833  changed |= r;
1834 
1835  /* DEBUG */ /* log_text("finding resulting array class: "); */
1836  if (elementclass.is_classref())
1837  common.ref = class_get_classref_multiarray_of(dimension,elementclass.ref);
1838  else {
1839  common.cls = class_multiarray_of(dimension,elementclass.cls,true);
1840  if (!common.cls) {
1841  exceptions_throw_internalerror("XXX Coult not create array class");
1842  return typecheck_FAIL;
1843  }
1844  }
1845  /* DEBUG */ /* utf_display_printable_ascii(common->name); printf("\n"); */
1846  }
1847  else {
1848  common.any = src->typeclass.any;
1849  }
1850  }
1851  }
1852  else {
1853  /* {We know that at least one of x or y is no array, so the
1854  * result cannot be an array.} */
1855 
1856  r = typeinfo_merge_nonarrays(this,
1857  &common,
1858  x->typeclass, src->typeclass,
1859  x->merged, src->merged);
1861  if (r == typecheck_FAIL)
1862  return r;
1863  changed |= r;
1864 
1865  dimension = 0;
1866  new_elementtype = ARRAYTYPE_INT;
1867  elementclass.any = NULL;
1868  }
1869 
1870  /* Put the new values into dest if neccessary. */
1871 
1872  if (this->typeclass.any != common.any) {
1873  this->typeclass.any = common.any;
1874  changed = true;
1875  }
1876  if (this->dimension != dimension) {
1877  this->dimension = dimension;
1878  changed = true;
1879  }
1880  if (elementtype != new_elementtype) {
1881  elementtype = new_elementtype;
1882  changed = true;
1883  }
1884  if (this->elementclass.any != elementclass.any) {
1885  this->elementclass.any = elementclass.any;
1886  changed = true;
1887  }
1888 
1889  return (typecheck_result) changed;
1890 }
1891 #endif /* ENABLE_VERIFER */
1892 
1893 
1894 /**********************************************************************/
1895 /* DEBUGGING HELPERS */
1896 /**********************************************************************/
1897 
1898 #ifdef TYPEINFO_DEBUG
1899 
1900 #if 0
1901 static int
1902 typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
1903 {
1904  if (a->any == b->any) return 0;
1905  if (a->any < b->any) return -1;
1906  return +1;
1907 }
1908 
1909 static void
1910 typeinfo_test_parse(typeinfo_t *info,char *str)
1911 {
1912  int num;
1913  int i;
1914  typeinfo_t *infobuf;
1915  u1 *typebuf;
1916  int returntype;
1917  Utf8String desc = Utf8String::from_utf8(str);
1918 
1919  num = typeinfo_count_method_args(desc,false);
1920  if (num) {
1921  typebuf = (u1*) DumpMemory::allocate(sizeof(u1) * num);
1922  infobuf = (typeinfo_t*) DumpMemory::allocate(sizeof(typeinfo_t) * num);
1923 
1924  typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
1925  &returntype,info);
1926 
1927  TYPEINFO_ALLOCMERGED(info->merged,num);
1928  info->merged->count = num;
1929 
1930  for (i=0; i<num; ++i) {
1931  if (typebuf[i] != TYPE_ADR) {
1932  log_text("non-reference type in mergedlist");
1933  assert(0);
1934  }
1935 
1936  info->merged->list[i].any = infobuf[i].typeclass.any;
1937  }
1938  qsort(info->merged->list,num,sizeof(classref_or_classinfo),
1939  (int(*)(const void *,const void *))&typeinfo_test_compare);
1940  }
1941  else {
1942  typeinfo_init_from_method_args(desc,NULL,NULL,0,false,
1943  &returntype,info);
1944  }
1945 }
1946 #endif
1947 
1948 #define TYPEINFO_TEST_BUFLEN 4000
1949 
1950 static bool
1952 {
1953  int i;
1954 
1955  if (x->typeclass.any != y->typeclass.any) return false;
1956  if (x->dimension != y->dimension) return false;
1957  if (x->dimension) {
1958  if (x->elementclass.any != y->elementclass.any) return false;
1959  if (x->elementtype != y->elementtype) return false;
1960  }
1961 
1962  if (x->is_newobject())
1964  return false;
1965 
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)
1971  return false;
1972  }
1973  return true;
1974 }
1975 
1976 static void
1978 {
1979  typeinfo_t dest;
1980 
1981  typeinfo_t::clone(*a,dest);
1982 
1983  printf("\n ");
1984  typeinfo_print_short(stdout,&dest);
1985  printf("\n ");
1986  typeinfo_print_short(stdout,b);
1987  printf("\n");
1988 
1989  typecheck_result r = dest.merge(NULL, b);
1990  if (r == typecheck_FAIL) {
1991  printf("EXCEPTION\n");
1992  return;
1993  }
1994 
1995  bool changed = (r) ? 1 : 0;
1996  bool changed_should_be = (!typeinfo_equal(&dest,a)) ? 1 : 0;
1997 
1998  printf(" %s\n",(changed) ? "changed" : "=");
1999 
2000  if (typeinfo_equal(&dest,result)) {
2001  printf("OK ");
2002  typeinfo_print_short(stdout,&dest);
2003  printf("\n");
2004  if (changed != changed_should_be) {
2005  printf("WRONG RETURN VALUE!\n");
2006  (*failed)++;
2007  }
2008  }
2009  else {
2010  printf("RESULT ");
2011  typeinfo_print_short(stdout,&dest);
2012  printf("\n");
2013  printf("SHOULD BE ");
2014  typeinfo_print_short(stdout,result);
2015  printf("\n");
2016  (*failed)++;
2017  }
2018 }
2019 
2020 #if 0
2021 static void
2022 typeinfo_inc_dimension(typeinfo_t *info)
2023 {
2024  if (info->dimension++ == 0) {
2025  info->elementtype = ARRAYTYPE_OBJECT;
2026  info->elementclass = info->typeclass;
2027  }
2028  info->typeclass = class_array_of(info->typeclass,true);
2029 }
2030 #endif
2031 
2032 #define TYPEINFO_TEST_MAXDIM 10
2033 
2034 static void
2035 typeinfo_testrun(const char *filename)
2036 {
2037  char buf[TYPEINFO_TEST_BUFLEN];
2038  char bufa[TYPEINFO_TEST_BUFLEN];
2039  char bufb[TYPEINFO_TEST_BUFLEN];
2040  char bufc[TYPEINFO_TEST_BUFLEN];
2041  typeinfo_t a,b,c;
2042  int maxdim;
2043  int failed = 0;
2044  FILE *file = fopen(filename,"rt");
2045  int res;
2046 
2047  if (!file) {
2048  log_text("could not open typeinfo test file");
2049  assert(0);
2050  }
2051 
2052  while (fgets(buf,TYPEINFO_TEST_BUFLEN,file)) {
2053  if (buf[0] == '#' || !strlen(buf))
2054  continue;
2055 
2056  res = sscanf(buf,"%s\t%s\t%s\n",bufa,bufb,bufc);
2057  if (res != 3 || !strlen(bufa) || !strlen(bufb) || !strlen(bufc)) {
2058  log_text("Invalid line in typeinfo test file (none of empty, comment or test)");
2059  assert(0);
2060  }
2061 
2062 #if 0
2063  typeinfo_test_parse(&a,bufa);
2064  typeinfo_test_parse(&b,bufb);
2065  typeinfo_test_parse(&c,bufc);
2066 #endif
2067 #if 0
2068  do {
2069 #endif
2070  typeinfo_testmerge(&a,&b,&c,&failed); /* check result */
2071  typeinfo_testmerge(&b,&a,&c,&failed); /* check commutativity */
2072 
2073  if (a.is_nulltype()) break;
2074  if (b.is_nulltype()) break;
2075  if (c.is_nulltype()) break;
2076 
2077  maxdim = a.dimension;
2078  if (b.dimension > maxdim) maxdim = b.dimension;
2079  if (c.dimension > maxdim) maxdim = c.dimension;
2080 
2081 #if 0
2082  if (maxdim < TYPEINFO_TEST_MAXDIM) {
2083  typeinfo_inc_dimension(&a);
2084  typeinfo_inc_dimension(&b);
2085  typeinfo_inc_dimension(&c);
2086  }
2087  } while (maxdim < TYPEINFO_TEST_MAXDIM);
2088 #endif
2089  }
2090 
2091  fclose(file);
2092 
2093  if (failed) {
2094  fprintf(stderr,"Failed typeinfo_merge tests: %d\n",failed);
2095  log_text("Failed test");
2096  assert(0);
2097  }
2098 }
2099 
2100 void
2102 {
2103  log_text("Running typeinfo test file...");
2104  typeinfo_testrun("typeinfo.tst");
2105  log_text("Finished typeinfo test file.");
2106 }
2107 
2108 #if 0
2109 void
2110 typeinfo_init_from_fielddescriptor(typeinfo_t *info,char *desc)
2111 {
2112  typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
2113 }
2114 #endif
2115 
2116 #define TYPEINFO_MAXINDENT 80
2117 
2118 void
2120 {
2121  /*fprintf(file,"<class %p>",c.any);*/
2122 
2123  if (!c.any) {
2124  fprintf(file,"<null>");
2125  }
2126  else {
2127  if (c.is_classref()) {
2128  fprintf(file,"<ref>");
2130  }
2131  else {
2133  }
2134  }
2135 }
2136 
2137 void
2138 typeinfo_print(FILE *file, const typeinfo_t *info, int indent)
2139 {
2140  char ind[TYPEINFO_MAXINDENT + 1];
2141 
2142  if (indent > TYPEINFO_MAXINDENT)
2143  indent = TYPEINFO_MAXINDENT;
2144 
2145  for (int i = 0; i < indent; ++i)
2146  ind[i] = ' ';
2147  ind[indent] = (char) 0;
2148 
2149  if (info->is_primitive()) {
2150  if (basicblock *bptr = (basicblock*) info->returnaddress())
2151  fprintf(file,"%sreturnAddress (L%03d)\n",ind,bptr->nr);
2152  else
2153  fprintf(file,"%sprimitive\n",ind);
2154  return;
2155  }
2156 
2157  if (info->is_nulltype()) {
2158  fprintf(file,"%snull\n",ind);
2159  return;
2160  }
2161 
2162  if (info->is_newobject()) {
2163  if (instruction *ins = info->newobject_instruction()) {
2164  fprintf(file,"%sNEW(%p):",ind,(void*)ins);
2165  typeinfo_print_class(file,ins[-1].sx.val.c);
2166  fprintf(file,"\n");
2167  }
2168  else {
2169  fprintf(file,"%sNEW(this)",ind);
2170  }
2171  return;
2172  }
2173 
2174  fprintf(file,"%sClass: ",ind);
2175  typeinfo_print_class(file,info->typeclass);
2176  fprintf(file,"\n");
2177 
2178  if (info->is_array()) {
2179  fprintf(file,"%sDimension: %d",ind,(int)info->dimension);
2180  fprintf(file,"\n%sElements: ",ind);
2181  switch (info->elementtype) {
2182  case ARRAYTYPE_INT : fprintf(file,"int\n"); break;
2183  case ARRAYTYPE_LONG : fprintf(file,"long\n"); break;
2184  case ARRAYTYPE_FLOAT : fprintf(file,"float\n"); break;
2185  case ARRAYTYPE_DOUBLE : fprintf(file,"double\n"); break;
2186  case ARRAYTYPE_BYTE : fprintf(file,"byte\n"); break;
2187  case ARRAYTYPE_CHAR : fprintf(file,"char\n"); break;
2188  case ARRAYTYPE_SHORT : fprintf(file,"short\n"); break;
2189  case ARRAYTYPE_BOOLEAN : fprintf(file,"boolean\n"); break;
2190 
2191  case ARRAYTYPE_OBJECT:
2192  typeinfo_print_class(file,info->elementclass);
2193  fprintf(file,"\n");
2194  break;
2195 
2196  default:
2197  fprintf(file,"INVALID ARRAYTYPE!\n");
2198  }
2199  }
2200 
2201  if (info->merged) {
2202  fprintf(file,"%sMerged: ",ind);
2203  for (int i = 0; i < info->merged->count; ++i) {
2204  if (i) fprintf(file,", ");
2205  typeinfo_print_class(file,info->merged->list[i]);
2206  }
2207  fprintf(file,"\n");
2208  }
2209 }
2210 
2211 void
2212 typeinfo_print_short(FILE *file, const typeinfo_t *info)
2213 {
2214  int i;
2215  instruction *ins;
2216  basicblock *bptr;
2217 
2218  /*fprintf(file,"<typeinfo %p>",info);*/
2219 
2220  if (!info) {
2221  fprintf(file,"(typeinfo*)NULL");
2222  return;
2223  }
2224 
2225  if (info->is_primitive()) {
2226  bptr = (basicblock*) info->returnaddress();
2227  if (bptr)
2228  fprintf(file,"ret(L%03d)",bptr->nr);
2229  else
2230  fprintf(file,"primitive");
2231  return;
2232  }
2233 
2234  if (info->is_nulltype()) {
2235  fprintf(file,"null");
2236  return;
2237  }
2238 
2239  if (info->is_newobject()) {
2240  ins = (instruction *) info->newobject_instruction();
2241  if (ins) {
2242  /*fprintf(file,"<ins %p>",ins);*/
2243  fprintf(file,"NEW(%p):",(void*)ins);
2244  typeinfo_print_class(file,ins[-1].sx.val.c);
2245  }
2246  else
2247  fprintf(file,"NEW(this)");
2248  return;
2249  }
2250 
2251  typeinfo_print_class(file,info->typeclass);
2252 
2253  if (info->merged) {
2254  fprintf(file,"{");
2255  for (i=0; i<info->merged->count; ++i) {
2256  if (i) fprintf(file,",");
2257  typeinfo_print_class(file,info->merged->list[i]);
2258  }
2259  fprintf(file,"}");
2260  }
2261 }
2262 
2263 void
2264 typeinfo_print_type(FILE *file, int type, const typeinfo_t *info)
2265 {
2266  switch (type) {
2267  case TYPE_VOID: fprintf(file,"V"); break;
2268  case TYPE_INT: fprintf(file,"I"); break;
2269  case TYPE_FLT: fprintf(file,"F"); break;
2270  case TYPE_DBL: fprintf(file,"D"); break;
2271  case TYPE_LNG: fprintf(file,"J"); break;
2272  case TYPE_RET: fprintf(file,"R:"); /* FALLTHROUGH! */
2273  case TYPE_ADR:
2274  typeinfo_print_short(file,info);
2275  break;
2276 
2277  default:
2278  fprintf(file,"!");
2279  }
2280 }
2281 
2282 void
2284 {
2285  typeinfo_print_type(file,td->type, &(td->typeinfo));
2286 }
2287 
2288 void
2289 typevector_print(FILE *file, const varinfo *vec, int size)
2290 {
2291  int i;
2292 
2293  for (i=0; i<size; ++i) {
2294  fprintf(file," %d=",i);
2295  typeinfo_print_type(file, vec[i].type, &(vec[i].typeinfo));
2296  }
2297 }
2298 
2299 #endif /* TYPEINFO_DEBUG */
2300 
2301 
2302 /*
2303  * These are local overrides for various environment variables in Emacs.
2304  * Please do not remove this and leave it at the end of the file, where
2305  * Emacs will automagically detect them.
2306  * ---------------------------------------------------------------------
2307  * Local variables:
2308  * mode: c++
2309  * indent-tabs-mode: t
2310  * c-basic-offset: 4
2311  * tab-width: 4
2312  * End:
2313  * vim:noexpandtab:sw=4:ts=4:
2314  */
void exceptions_throw_verifyerror(methodinfo *m, const char *message,...)
Definition: exceptions.cpp:973
#define TYPEINFO_TEST_BUFLEN
Definition: typeinfo.cpp:1948
val_operand_t val
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
static bool typeinfo_init_varinfo_from_typedesc(varinfo *var, typedesc *desc)
Definition: typeinfo.cpp:960
std::size_t index
bool typeinfo_init_varinfos_from_methoddesc(varinfo *vars, methoddesc *desc, int buflen, int startindex, s4 *map, typedescriptor_t *returntype)
Definition: typeinfo.cpp:1008
typeinfo_t typeinfo
Definition: typeinfo.hpp:382
void init_class(classinfo *c)
Initialize object type.
Definition: typeinfo.cpp:790
constant_classref * class_get_classref_component_of(constant_classref *ref)
Definition: class.cpp:1094
ArrayType elementtype
Definition: array.hpp:76
static bool typeinfo_merge_mergedlists(typeinfo_t *dest, typeinfo_mergedlist_t *x, typeinfo_mergedlist_t *y)
Definition: typeinfo.cpp:1315
classref_or_classinfo list[1]
Definition: typeinfo.hpp:374
bool is_classref() const
Definition: references.hpp:66
#define TYPEINFO_ASSERT(cond)
Definition: typeinfo.cpp:62
classinfo * super
Definition: class.hpp:102
int typedescriptors_init_from_methoddesc(typedescriptor_t *td, methoddesc *desc, int buflen, bool twoword, int startindex, typedescriptor_t *returntype)
Definition: typeinfo.cpp:1088
size_t size() const
Definition: utf8.hpp:161
classinfo * class_array_of(classinfo *component, bool link)
Definition: class.cpp:832
bool init_component(const typeinfo_t &srcarray)
Definition: typeinfo.cpp:1144
s4 state
Definition: class.hpp:115
varinfo * var
Definition: jit.hpp:148
classref_or_classinfo elementclass
Definition: typeinfo.hpp:237
bool is_newobject() const
Definition: typeinfo.hpp:246
bool typevector_checkretaddr(varinfo *vec, int index)
Definition: typeinfo.cpp:175
static bool typedescriptor_init_from_typedesc(typedescriptor_t *td, typedesc *desc)
Definition: typeinfo.cpp:928
int32_t interfacescount
Definition: class.hpp:106
vftbl_t * componentvftbl
Definition: array.hpp:73
constant_classref * ref
Definition: references.hpp:62
#define DNEW_TYPEVECTOR(size)
Definition: typeinfo.hpp:403
uint8_t u1
Definition: types.hpp:40
static typecheck_result merged_implements_interface(classinfo *typeclass, typeinfo_mergedlist_t *merged, classinfo *interf)
Definition: typeinfo.cpp:483
Type type
Definition: reg.hpp:44
classinfo * pseudo_class_Arraystub
Definition: globals.cpp:106
classinfo * class_java_lang_Object
Definition: globals.cpp:28
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
Definition: reg.hpp:43
static bool typeinfo_merge_add(typeinfo_t *dest, typeinfo_mergedlist_t *m, classref_or_classinfo cls)
Definition: typeinfo.cpp:1258
classinfo * class_multiarray_of(s4 dim, classinfo *element, bool link)
Definition: class.cpp:881
classinfo * pseudo_class_Null
Definition: globals.cpp:107
static bool interface_extends_interface(classinfo *cls, classinfo *interf)
Definition: typeinfo.cpp:349
void init_primitive()
Definition: typeinfo.hpp:290
void typevector_print(FILE *file, const varinfo *vec, int size)
Definition: typeinfo.cpp:2289
bool is_array() const
Definition: typeinfo.hpp:260
typedesc paramtypes[1]
Definition: descriptor.hpp:167
typecheck_result typevector_merge(methodinfo *m, varinfo *dst, varinfo *y, int size)
Definition: typeinfo.cpp:285
bool typevector_init_object(varinfo *set, void *ins, classref_or_classinfo initclass, int size)
Definition: typeinfo.cpp:245
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
ArrayType
Definition: array.hpp:51
Indent indent
Definition: OStream.cpp:54
typecheck_result merge(methodinfo *m, const typeinfo_t *t)
functions for merging types
Definition: typeinfo.cpp:1672
classref_or_classinfo c
#define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
Definition: typeinfo.cpp:771
static bool typeinfo_merge_two(typeinfo_t *dest, classref_or_classinfo clsx, classref_or_classinfo clsy)
Definition: typeinfo.cpp:1234
void init_returnaddress(void *adr)
Definition: typeinfo.hpp:298
typeinfo_t typeinfo
Definition: reg.hpp:56
Instruction::InstID tmp[]
Definition: Matcher.cpp:55
Utf8String name
Definition: class.hpp:91
classinfo * clazz
Definition: vftbl.hpp:100
#define TYPEVECTOR_SIZE(size)
Definition: typeinfo.hpp:400
Definition: set.cpp:44
static typecheck_result typeinfo_merge_nonarrays(typeinfo_t *dest, classref_or_classinfo *result, classref_or_classinfo x, classref_or_classinfo y, typeinfo_mergedlist_t *mergedx, typeinfo_mergedlist_t *mergedy)
Definition: typeinfo.cpp:1439
void typeinfo_print_type(FILE *file, int type, const typeinfo_t *info)
Definition: typeinfo.cpp:2264
Type
Types used internally by JITTED code.
Definition: global.hpp:117
bool is_nulltype() const
Definition: typeinfo.hpp:245
void exceptions_throw_internalerror(const char *message,...)
Definition: exceptions.cpp:805
static void clone_merged(const typeinfo_t &src, typeinfo_t &dst)
Definition: typeinfo.cpp:1194
s4 flags
Definition: class.hpp:90
void typevector_copy_inplace(varinfo *src, varinfo *dst, int size)
Definition: typeinfo.cpp:111
typeinfo_mergedlist_t * merged
Definition: typeinfo.hpp:238
typecheck_result is_assignable_to(typeinfo_t *dest) const
Definition: typeinfo.cpp:751
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
bool typevector_checkreference(varinfo *vec, int index)
Definition: typeinfo.cpp:154
void * returnaddress() const
Definition: typeinfo.hpp:248
MIIterator i
constant_classref * class_get_classref(classinfo *cls, Utf8String name)
Definition: class.cpp:985
typedesc returntype
Definition: descriptor.hpp:166
typecheck_result is_assignable_to_class(classref_or_classinfo dest) const
Definition: typeinfo.cpp:586
bool is_primitive() const
Definition: typeinfo.hpp:242
#define TYPEINFO_MAXINDENT
Definition: typeinfo.cpp:2116
int32_t s4
Definition: types.hpp:45
void typeinfo_print(FILE *file, const typeinfo_t *info, int indent)
Definition: typeinfo.cpp:2138
s4 index
Definition: class.hpp:116
#define CLASSREF_OR_CLASSINFO_NAME(value)
Definition: references.hpp:194
#define TYPEINFO_ALLOCMERGED(mergedlist, count)
Definition: typeinfo.cpp:765
static bool typeinfo_equal(typeinfo_t *x, typeinfo_t *y)
Definition: typeinfo.cpp:1951
instruction * newobject_instruction() const
Definition: typeinfo.hpp:254
bool class_issubclass(classinfo *sub, classinfo *super)
Definition: class.cpp:1404
classinfo ** interfaces
Definition: class.hpp:107
arraydescriptor * arraydesc
Definition: vftbl.hpp:101
void init_nulltype()
Definition: typeinfo.hpp:335
void utf_fprint_printable_ascii(FILE *file, Utf8String u)
Definition: utf8.cpp:650
bool init_from_typedesc(const typedesc *desc, u1 *type)
Definition: typeinfo.cpp:889
classref_or_classinfo typeclass
Definition: typeinfo.hpp:236
#define CLASSINFO_IS_ARRAY(clsinfo)
Definition: typeinfo.cpp:50
vftbl_t * elementvftbl
Definition: array.hpp:74
vftbl_t * vftbl
Definition: class.hpp:121
void typeinfo_print_short(FILE *file, const typeinfo_t *info)
Definition: typeinfo.cpp:2212
byte_iterator begin() const
Definition: utf8.hpp:106
void typevector_store(varinfo *vec, int index, Type type, typeinfo_t *info)
Definition: typeinfo.cpp:195
classinfo * pseudo_class_New
Definition: globals.cpp:108
void typevector_store_retaddr(varinfo *vec, int index, typeinfo_t *info)
Definition: typeinfo.cpp:216
methodinfo * m
Definition: jit.hpp:127
jmethodID jint const void jint const jvmtiAddrLocationMap * map
Definition: jvmti.h:338
#define TYPEINFO_TEST_MAXDIM
Definition: typeinfo.cpp:2032
classinfo * link_class(classinfo *c)
Definition: linker.cpp:378
bool is_reference() const
Definition: reg.hpp:59
void typeinfo_print_class(FILE *file, classref_or_classinfo c)
Definition: typeinfo.cpp:2119
static void * allocate(size_t size)
Definition: dumpmemory.hpp:251
#define CLASSINFO_IMPLEMENTS_INTERFACE(cls, index)
Definition: typeinfo.cpp:53
s4 nr
Definition: jit.hpp:312
static typecheck_result merged_is_subclass(classinfo *typeclass, typeinfo_mergedlist_t *merged, classinfo *cls)
Definition: typeinfo.cpp:530
bool resolve_classref_or_classinfo(methodinfo *refmethod, classref_or_classinfo cls, resolve_mode_t mode, bool checkaccess, bool link, classinfo **result)
Definition: resolve.cpp:351
void typedescriptor_print(FILE *file, const typedescriptor_t *td)
Definition: typeinfo.cpp:2283
classinfo *const referer
Definition: references.hpp:47
static void typeinfo_merge_error(methodinfo *m, const char *str, const typeinfo_t *x, const typeinfo_t *y)
Definition: typeinfo.cpp:1217
void descriptor_debug_print_typedesc(FILE *file, typedesc *d)
static void typeinfo_testrun(const char *filename)
Definition: typeinfo.cpp:2035
bool is_returnaddress() const
Definition: reg.hpp:58
#define str(x)
static typecheck_result mergedlist_implements_interface(typeinfo_mergedlist_t *merged, classinfo *interf)
Definition: typeinfo.cpp:433
#define log_text(s)
Definition: logging.hpp:170
ArrayType elementtype
Definition: typeinfo.hpp:240
static typecheck_result classinfo_implements_interface(classinfo *cls, classinfo *interf)
Definition: typeinfo.cpp:390
const Utf8String name
Definition: references.hpp:48
#define printf(...)
Definition: ssa2.cpp:40
void typeinfo_test()
Definition: typeinfo.cpp:2101
bool typevector_checktype(varinfo *vec, int index, int type)
Definition: typeinfo.cpp:132
constant_classref * classref
Definition: descriptor.hpp:135
constant_classref * class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
Definition: class.cpp:1038
static void clone(const typeinfo_t &src, typeinfo_t &dst)
Definition: typeinfo.hpp:357
static void typeinfo_testmerge(typeinfo_t *a, typeinfo_t *b, typeinfo_t *result, int *failed)
Definition: typeinfo.cpp:1977
bool is_classinfo() const
Definition: references.hpp:67
varinfo * typevector_copy(varinfo *src, int size)
Definition: typeinfo.cpp:87
typecheck_result
Definition: typeinfo.hpp:81