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 $
*/
/* DEBUG HELPERS */
/****************************************************************************/
+/*#define DESCRIPTOR_VERBOSE*/
+
#ifndef NDEBUG
#define DESCRIPTOR_DEBUG
#endif
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);
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);
return false;
if (name)
- descriptor_pool_add_class(pool, name);
+ if (!descriptor_pool_add_class(pool, name))
+ return false;
}
if (utf_ptr == end_pos) {
return false;
if (name)
- descriptor_pool_add_class(pool,name);
+ if (!descriptor_pool_add_class(pool,name))
+ return false;
if (argcount > 255) {
*exceptionptr =
} else {
/* a field descriptor */
+
pool->fieldcount++;
if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
return false;
if (name)
- descriptor_pool_add_class(pool,name);
+ if (!descriptor_pool_add_class(pool,name))
+ return false;
}
d->paramslots = argcount;
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;
}
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) +
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
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;
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);
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 */
td->type = TYPE_ADR;
td->decltype = TYPE_ADR;
td->arraydim = 0;
- td->classref = NULL;
+ td->classref = thisclass;
td++;
pool->descriptors_next += sizeof(typedesc);
/* 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 */
/* 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 */
/* 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);
}
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++;
/* 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;
}
}
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) {
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
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));
}