* renamed CACAO_TYPECHECK to ENABLE_VERIFIER
[cacao.git] / src / vm / descriptor.c
index bf00fe19812afe7ab1b83fc06c007fa336c0c08d..3aeec22ee43e3cb892ad9263041a9dc7351759f7 100644 (file)
@@ -27,8 +27,9 @@
    Authors: Edwin Steiner
 
    Changes: Christian Thalinger
+            Christian Ullrich
 
-   $Id: descriptor.c 2737 2005-06-18 14:55:20Z edwin $
+   $Id: descriptor.c 3386 2005-10-07 14:02:52Z edwin $
 
 */
 
@@ -122,6 +123,8 @@ struct descriptor_hash_entry {
 /* DEBUG HELPERS                                                            */
 /****************************************************************************/
 
+/*#define DESCRIPTOR_VERBOSE*/
+
 #ifndef NDEBUG
 #define DESCRIPTOR_DEBUG
 #endif
@@ -387,6 +390,11 @@ descriptor_pool_add_class(descriptor_pool *pool, utf *name)
        DESCRIPTOR_ASSERT(pool);
        DESCRIPTOR_ASSERT(name);
 
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_add_class(%p,",(void*)pool);
+       utf_fprint(stderr,name);fprintf(stderr,")\n");
+#endif
+
        /* find a place in the hashtable */
 
        key = utf_hashkey(name->text, name->blength);
@@ -447,6 +455,11 @@ descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
        utf *name;
        s4 argcount = 0;
        
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_add(%p,",(void*)pool);
+       utf_fprint(stderr,desc);fprintf(stderr,")\n");
+#endif
+
        DESCRIPTOR_ASSERT(pool);
        DESCRIPTOR_ASSERT(desc);
 
@@ -508,7 +521,8 @@ descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
                                return false;
 
                        if (name)
-                               descriptor_pool_add_class(pool, name);
+                               if (!descriptor_pool_add_class(pool, name))
+                                       return false;
                }
 
                if (utf_ptr == end_pos) {
@@ -523,7 +537,8 @@ descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
                        return false;
 
                if (name)
-                       descriptor_pool_add_class(pool,name);
+                       if (!descriptor_pool_add_class(pool,name))
+                               return false;
 
                if (argcount > 255) {
                        *exceptionptr =
@@ -533,6 +548,7 @@ descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
 
        } else {
                /* a field descriptor */
+
                pool->fieldcount++;
                
            if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
@@ -541,7 +557,8 @@ descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
                        return false;
 
                if (name)
-                       descriptor_pool_add_class(pool,name);
+                       if (!descriptor_pool_add_class(pool,name))
+                               return false;
        }
 
        d->paramslots = argcount;
@@ -634,9 +651,7 @@ descriptor_pool_lookup_classref(descriptor_pool *pool, utf *classname)
                c = c->hashlink;
        }
 
-       *exceptionptr =
-               new_exception_message(string_java_lang_InternalError,
-                                                         "Class reference not found in descriptor pool");
+       *exceptionptr = new_internalerror("Class reference not found in descriptor pool");
        return NULL;
 }
 
@@ -661,8 +676,8 @@ descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool)
        
        DESCRIPTOR_ASSERT(pool);
 
-       /* XXX TWISTI: paramcount + 1: we don't know if the method is static or   */
-       /* not, i have no better solution yet.                                    */
+       /* TWISTI: paramcount + 1: we don't know if the method is static or   */
+       /* not, i have no better solution yet.                                */
 
        size =
                pool->fieldcount * sizeof(typedesc) +
@@ -759,6 +774,9 @@ descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc)
        pool.............the descriptor_pool
        desc.............the method descriptor
        mflags...........the method flags
+          thisclass........classref to the class containing the method.
+                                               This is ignored if mflags contains ACC_STATIC.
+                                               The classref is stored for inserting the 'this' argument.
 
    RETURN VALUE:
        a pointer to the parsed method descriptor, or
@@ -772,7 +790,7 @@ descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc)
 
 methoddesc * 
 descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
-                                                                               s4 mflags)
+                                                                               s4 mflags,constant_classref *thisclass)
 {
        u4 key, slot;
        descriptor_hash_entry *d;
@@ -783,10 +801,24 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
        s2 paramcount = 0;
        s2 paramslots = 0;
 
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_parse_method_descriptor(%p,%d,%p,",
+                       (void*)pool,(int)mflags,(void*)thisclass);
+       utf_fprint(stderr,desc); fprintf(stderr,")\n");
+#endif
+
        DESCRIPTOR_ASSERT(pool);
        DESCRIPTOR_ASSERT(pool->descriptors);
        DESCRIPTOR_ASSERT(pool->descriptors_next);
 
+       /* check that it is a method descriptor */
+       
+       if (desc->text[0] != '(') {
+               *exceptionptr = new_classformaterror(pool->referer,
+                               "Field descriptor used in method reference");
+               return NULL;
+       }
+
        /* lookup the descriptor in the hashtable */
 
        key = utf_hashkey(desc->text, desc->blength);
@@ -807,15 +839,9 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
        md = (methoddesc *) pool->descriptors_next;
        pool->descriptors_next += sizeof(methoddesc) - sizeof(typedesc);
 
-       utf_ptr = desc->text;
+       utf_ptr = desc->text + 1; /* skip '(' */
        end_pos = UTF_END(desc);
 
-       if (*utf_ptr++ != '(') {
-               *exceptionptr = new_classformaterror(pool->referer,
-                               "Field descriptor used in method reference");
-               return NULL;
-       }
-
        td = md->paramtypes;
 
        /* count the `this' pointer */
@@ -824,7 +850,7 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
                td->type = TYPE_ADR;
                td->decltype = TYPE_ADR;
                td->arraydim = 0;
-               td->classref = NULL;
+               td->classref = thisclass;
 
                td++;
                pool->descriptors_next += sizeof(typedesc);
@@ -850,9 +876,14 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
 
        /* Skip possible `this' pointer in paramtypes array to allow a possible   */
        /* memory move later in parse.                                            */
+       /* We store the thisclass reference, so we can later correctly fill in    */
+       /* the parameter slot of the 'this' argument.                             */
 
-       if (mflags == ACC_UNDEF)
+       if (mflags == ACC_UNDEF) {
+               td->classref = thisclass;
+               td++;
                pool->descriptors_next += sizeof(typedesc);
+       }
 
        /* parse return type */
 
@@ -871,14 +902,15 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
                        /* allocate memory for params */
 
                        md->params = MNEW(paramdesc, md->paramcount);
-
-                       /* fill the paramdesc */
-
-                       md_param_alloc(md);
                }
                else {
                        md->params = METHODDESC_NOPARAMS;
                }
+
+               /* fill the paramdesc */
+               /* md_param_alloc has to be called if md->paramcount == 0, too, so it */
+               /* can make the reservation for the Linkage Area, Return Register...  */
+               md_param_alloc(md);
        }
        else {
                /* params will be allocated later by descriptor_params_from_paramtypes */
@@ -928,9 +960,14 @@ bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
        /* check for `this' pointer */
 
        if (!(mflags & ACC_STATIC)) {
+               constant_classref *thisclass;
+
+               /* fetch class reference from reserved param slot */
+               thisclass = td[md->paramcount].classref;
+               DESCRIPTOR_ASSERT(thisclass);
+
                if (md->paramcount > 0) {
                        /* shift param types by 1 argument */
-
                        MMOVE(td + 1, td, typedesc, md->paramcount);
                }
 
@@ -939,7 +976,7 @@ bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
                td->type = TYPE_ADR;
                td->decltype = TYPE_ADR;
                td->arraydim = 0;
-               td->classref = NULL; /* XXX classref to invokant class */
+               td->classref = thisclass;
 
                md->paramcount++;
                md->paramslots++;
@@ -951,15 +988,17 @@ bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
                /* allocate memory for params */
 
                md->params = MNEW(paramdesc, md->paramcount);
-
-               /* fill the paramdesc */
-
-               md_param_alloc(md);
        }
        else {
                md->params = METHODDESC_NOPARAMS;
        }
 
+       /* fill the paramdesc */
+       /* md_param_alloc has to be called if md->paramcount == 0, too, so     */
+       /* it can make the reservation for the Linkage Area, Return Register.. */
+
+       md_param_alloc(md);
+
        return true;
 }
 
@@ -1051,7 +1090,10 @@ descriptor_debug_print_typedesc(FILE *file,typedesc *d)
        }
        
        if (d->type == TYPE_ADDRESS) {
-               utf_fprint(file,d->classref->name);
+               if (d->classref)
+                       utf_fprint(file,d->classref->name);
+               else
+                       fprintf(file,"<class=NULL>");
        }
        else {
                switch (d->decltype) {
@@ -1072,6 +1114,32 @@ descriptor_debug_print_typedesc(FILE *file,typedesc *d)
                fprintf(file,"[%d]",d->arraydim);
 }
 
+/* descriptor_debug_print_paramdesc ********************************************
+   Print the given paramdesc to the given stream
+
+   IN:
+          file.............stream to print to
+          d................the parameter descriptor
+
+*******************************************************************************/
+
+void
+descriptor_debug_print_paramdesc(FILE *file,paramdesc *d)
+{
+       if (!d) {
+               fprintf(file,"(paramdesc *)NULL");
+               return;
+       }
+       
+       if (d->inmemory) {
+               fprintf(file,"<m%d>",d->regoff);
+       }
+       else {
+               fprintf(file,"<r%d>",d->regoff);
+       }
+}
+
 /* descriptor_debug_print_methoddesc *******************************************
  
    Print the given methoddesc to the given stream
@@ -1097,7 +1165,12 @@ descriptor_debug_print_methoddesc(FILE *file,methoddesc *d)
                if (i)
                        fputc(',',file);
                descriptor_debug_print_typedesc(file,d->paramtypes + i);
+               if (d->params) {
+                       descriptor_debug_print_paramdesc(file,d->params + i);
+               }
        }
+       if (d->params == METHODDESC_NOPARAMS)
+               fputs("<NOPARAMS>",file);
        fputc(')',file);
        descriptor_debug_print_typedesc(file,&(d->returntype));
 }