/* src/vm/jit/verify/typeinfo.c - type system used by the type checker
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: typeinfo.c 7486 2007-03-08 13:50:07Z twisti $
-
*/
#include <string.h>
#include "mm/memory.h"
+
#include "toolbox/logging.h"
-#include "vm/exceptions.h"
+#include "vm/array.h"
+#include "vm/class.h"
+#include "vm/descriptor.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/primitive.hpp"
+#include "vm/resolve.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/verify/typeinfo.h"
-#include "vmcore/class.h"
-#include "vmcore/descriptor.h"
-#include "vmcore/loader.h"
-#include "vm/resolve.h"
-
/* check if a linked class is an array class. Only use for linked classes! */
#define CLASSINFO_IS_ARRAY(clsinfo) ((clsinfo)->vftbl->arraydesc != NULL)
*******************************************************************************/
void
-typevector_store(varinfo *vec,int index,int type,typeinfo *info)
+typevector_store(varinfo *vec,int index,int type,typeinfo_t *info)
{
TYPEINFO_ASSERT(vec);
*******************************************************************************/
void
-typevector_store_retaddr(varinfo *vec,int index,typeinfo *info)
+typevector_store_retaddr(varinfo *vec,int index,typeinfo_t *info)
{
TYPEINFO_ASSERT(vec);
TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
*******************************************************************************/
bool
-typeinfo_is_array(typeinfo *info)
+typeinfo_is_array(typeinfo_t *info)
{
TYPEINFO_ASSERT(info);
return TYPEINFO_IS_ARRAY(*info);
*******************************************************************************/
bool
-typeinfo_is_primitive_array(typeinfo *info,int arraytype)
+typeinfo_is_primitive_array(typeinfo_t *info,int arraytype)
{
TYPEINFO_ASSERT(info);
return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
*******************************************************************************/
bool
-typeinfo_is_array_of_refs(typeinfo *info)
+typeinfo_is_array_of_refs(typeinfo_t *info)
{
TYPEINFO_ASSERT(info);
return TYPEINFO_IS_ARRAY_OF_REFS(*info);
/* first check direct superinterfaces */
for (i=0; i<cls->interfacescount; ++i) {
- if (cls->interfaces[i].cls == interf)
+ if (cls->interfaces[i] == interf)
return true;
}
/* check indirect superinterfaces */
for (i=0; i<cls->interfacescount; ++i) {
- if (interface_extends_interface(cls->interfaces[i].cls,interf))
+ if (interface_extends_interface(cls->interfaces[i],interf))
return true;
}
*******************************************************************************/
static typecheck_result
-mergedlist_implements_interface(typeinfo_mergedlist *merged,
+mergedlist_implements_interface(typeinfo_mergedlist_t *merged,
classinfo *interf)
{
int i;
*******************************************************************************/
static typecheck_result
-merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist_t *merged,
classinfo *interf)
{
typecheck_result r;
*******************************************************************************/
static typecheck_result
-merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist_t *merged,
classinfo *cls)
{
int i;
*******************************************************************************/
typecheck_result
-typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
+typeinfo_is_assignable_to_class(typeinfo_t *value,classref_or_classinfo dest)
{
classref_or_classinfo c;
classinfo *cls;
arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
int dimension = arraydesc->dimension;
classinfo *elementclass = (arraydesc->elementvftbl)
- ? arraydesc->elementvftbl->class : NULL;
+ ? arraydesc->elementvftbl->clazz : NULL;
/* We are assigning to an array type. */
if (!TYPEINFO_IS_ARRAY(*value))
*******************************************************************************/
typecheck_result
-typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
+typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest)
{
TYPEINFO_ASSERT(value);
TYPEINFO_ASSERT(dest);
*******************************************************************************/
void
-typeinfo_init_classinfo(typeinfo *info, classinfo *c)
+typeinfo_init_classinfo(typeinfo_t *info, classinfo *c)
{
if ((info->typeclass.cls = c)->vftbl->arraydesc) {
if (c->vftbl->arraydesc->elementvftbl)
- info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->class;
+ info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->clazz;
else
info->elementclass.any = NULL;
info->dimension = c->vftbl->arraydesc->dimension;
*******************************************************************************/
bool
-typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
+typeinfo_init_class(typeinfo_t *info,classref_or_classinfo c)
{
char *utf_ptr;
int len;
*******************************************************************************/
bool
-typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
+typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo_t *info)
{
TYPEINFO_ASSERT(desc);
*******************************************************************************/
bool
-typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
+typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo_t *infobuf,
int buflen,bool twoword,
- u1 *returntype,typeinfo *returntypeinfo)
+ u1 *returntype,typeinfo_t *returntypeinfo)
{
int i;
int args = 0;
*******************************************************************************/
bool
-typedescriptor_init_from_typedesc(typedescriptor *td,
+typedescriptor_init_from_typedesc(typedescriptor_t *td,
typedesc *desc)
{
TYPEINFO_ASSERT(td);
methoddesc *desc,
int buflen, int startindex,
s4 *map,
- typedescriptor *returntype)
+ typedescriptor_t *returntype)
{
s4 i;
- s4 index;
+ s4 varindex;
s4 type;
s4 slot = 0;
/* check arguments */
for (i=startindex; i<desc->paramcount; ++i) {
type = desc->paramtypes[i].type;
- index = map[5*slot + type];
+ varindex = map[5*slot + type];
slot++;
if (IS_2_WORD_TYPE(type))
slot++;
- if (index == UNUSED)
+ if (varindex == UNUSED)
continue;
- if (index >= buflen) {
+ if (varindex >= buflen) {
exceptions_throw_internalerror("Buffer too small for method arguments.");
return false;
}
- if (!typeinfo_init_varinfo_from_typedesc(vars + index, desc->paramtypes + i))
+ if (!typeinfo_init_varinfo_from_typedesc(vars + varindex, desc->paramtypes + i))
return false;
}
*******************************************************************************/
int
-typedescriptors_init_from_methoddesc(typedescriptor *td,
+typedescriptors_init_from_methoddesc(typedescriptor_t *td,
methoddesc *desc,
int buflen,bool twoword,int startindex,
- typedescriptor *returntype)
+ typedescriptor_t *returntype)
{
int i;
int args = 0;
*******************************************************************************/
bool
-typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
+typeinfo_init_component(typeinfo_t *srcarray,typeinfo_t *dst)
{
- typeinfo_mergedlist *merged;
+ typeinfo_mergedlist_t *merged;
TYPEINFO_ASSERT(srcarray);
TYPEINFO_ASSERT(dst);
comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
if (comp)
- typeinfo_init_classinfo(dst,comp->class);
+ typeinfo_init_classinfo(dst,comp->clazz);
else
TYPEINFO_INIT_PRIMITIVE(*dst);
}
*******************************************************************************/
void
-typeinfo_clone(typeinfo *src,typeinfo *dest)
+typeinfo_clone(typeinfo_t *src,typeinfo_t *dest)
{
int count;
classref_or_classinfo *srclist,*destlist;
*******************************************************************************/
void
-typeinfo_free(typeinfo *info)
+typeinfo_free(typeinfo_t *info)
{
TYPEINFO_FREEMERGED_IF_ANY(info->merged);
info->merged = NULL;
static
void
-typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
+typeinfo_merge_error(methodinfo *m,char *str,typeinfo_t *x,typeinfo_t *y) {
#ifdef TYPEINFO_VERBOSE
fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
fprintf(stderr,"Typeinfo x:\n");
/* Returns: true if dest was changed (currently always true). */
static
bool
-typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
+typeinfo_merge_two(typeinfo_t *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
{
TYPEINFO_ASSERT(dest);
TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
/* Returns: true if dest was changed. */
static
bool
-typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo cls)
+typeinfo_merge_add(typeinfo_t *dest,typeinfo_mergedlist_t *m,classref_or_classinfo cls)
{
int count;
- typeinfo_mergedlist *newmerged;
+ typeinfo_mergedlist_t *newmerged;
classref_or_classinfo *mlist,*newlist;
count = m->count;
/* Returns: true if dest was changed. */
static
bool
-typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
- typeinfo_mergedlist *y)
+typeinfo_merge_mergedlists(typeinfo_t *dest,typeinfo_mergedlist_t *x,
+ typeinfo_mergedlist_t *y)
{
int count = 0;
int countx,county;
- typeinfo_mergedlist *temp,*result;
+ typeinfo_mergedlist_t *temp,*result;
classref_or_classinfo *clsx,*clsy,*newlist;
/* count the elements that will be in the resulting list */
*******************************************************************************/
static typecheck_result
-typeinfo_merge_nonarrays(typeinfo *dest,
+typeinfo_merge_nonarrays(typeinfo_t *dest,
classref_or_classinfo *result,
classref_or_classinfo x,classref_or_classinfo y,
- typeinfo_mergedlist *mergedx,
- typeinfo_mergedlist *mergedy)
+ typeinfo_mergedlist_t *mergedx,
+ typeinfo_mergedlist_t *mergedy)
{
classref_or_classinfo t;
classinfo *tcls,*common;
- typeinfo_mergedlist *tmerged;
+ typeinfo_mergedlist_t *tmerged;
bool changed;
typecheck_result r;
utf *xname;
#ifdef TYPEINFO_VERBOSE
{
- typeinfo dbgx,dbgy;
+ typeinfo_t dbgx,dbgy;
fprintf(stderr,"merge_nonarrays:\n");
fprintf(stderr," ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,xname);fprintf(stderr,"\n");
fprintf(stderr," ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,yname);fprintf(stderr,"\n");
/* {We know: y is at least as deep in the hierarchy as x.} */
/* Find nearest common anchestor for the classes. */
+
common = x.cls;
- tcls = y.cls;
+ tcls = y.cls;
+
while (tcls->index > common->index)
- tcls = tcls->super.cls;
+ tcls = tcls->super;
+
while (common != tcls) {
- common = common->super.cls;
- tcls = tcls->super.cls;
+ common = common->super;
+ tcls = tcls->super;
}
/* {common == nearest common anchestor of x and y.} */
*******************************************************************************/
typecheck_result
-typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y)
+typeinfo_merge(methodinfo *m,typeinfo_t *dest,typeinfo_t* y)
{
- typeinfo *x;
- typeinfo *tmp;
+ typeinfo_t *x;
+ typeinfo_t *tmp;
classref_or_classinfo common;
classref_or_classinfo elementclass;
int dimension;
}
static void
-typeinfo_test_parse(typeinfo *info,char *str)
+typeinfo_test_parse(typeinfo_t *info,char *str)
{
int num;
int i;
- typeinfo *infobuf;
+ typeinfo_t *infobuf;
u1 *typebuf;
int returntype;
utf *desc = utf_new_char(str);
num = typeinfo_count_method_args(desc,false);
if (num) {
typebuf = DMNEW(u1,num);
- infobuf = DMNEW(typeinfo,num);
+ infobuf = DMNEW(typeinfo_t,num);
typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
&returntype,info);
#define TYPEINFO_TEST_BUFLEN 4000
static bool
-typeinfo_equal(typeinfo *x,typeinfo *y)
+typeinfo_equal(typeinfo_t *x,typeinfo_t *y)
{
int i;
}
static void
-typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
+typeinfo_testmerge(typeinfo_t *a,typeinfo_t *b,typeinfo_t *result,int *failed)
{
- typeinfo dest;
+ typeinfo_t dest;
bool changed,changed_should_be;
typecheck_result r;
#if 0
static void
-typeinfo_inc_dimension(typeinfo *info)
+typeinfo_inc_dimension(typeinfo_t *info)
{
if (info->dimension++ == 0) {
info->elementtype = ARRAYTYPE_OBJECT;
char bufa[TYPEINFO_TEST_BUFLEN];
char bufb[TYPEINFO_TEST_BUFLEN];
char bufc[TYPEINFO_TEST_BUFLEN];
- typeinfo a,b,c;
+ typeinfo_t a,b,c;
int maxdim;
int failed = 0;
FILE *file = fopen(filename,"rt");
#if 0
void
-typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc)
+typeinfo_init_from_fielddescriptor(typeinfo_t *info,char *desc)
{
typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
}
}
void
-typeinfo_print(FILE *file,typeinfo *info,int indent)
+typeinfo_print(FILE *file,typeinfo_t *info,int indent)
{
int i;
char ind[TYPEINFO_MAXINDENT + 1];
}
void
-typeinfo_print_short(FILE *file,typeinfo *info)
+typeinfo_print_short(FILE *file,typeinfo_t *info)
{
int i;
instruction *ins;
}
void
-typeinfo_print_type(FILE *file,int type,typeinfo *info)
+typeinfo_print_type(FILE *file,int type,typeinfo_t *info)
{
switch (type) {
case TYPE_VOID: fprintf(file,"V"); break;
}
void
-typedescriptor_print(FILE *file,typedescriptor *td)
+typedescriptor_print(FILE *file,typedescriptor_t *td)
{
typeinfo_print_type(file,td->type,&(td->typeinfo));
}