home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
kaffe-0.5p4-src.tgz
/
tar.out
/
contrib
/
kaffe
/
kaffevm
/
constants.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
5KB
|
243 lines
/*
* constants.c
* Constant management.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
*/
#define RDBG(s)
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "gtypes.h"
#include "slots.h"
#include "access.h"
#include "object.h"
#include "constants.h"
#include "object.h"
#include "classMethod.h"
#include "file.h"
extern classes* CharArrayClass;
static strconst* strhash[STRHASHSZ];
static strpair* strpairhash[STRHASHSZ];
/*
* Read in constant pool from opened file.
*/
constants*
readConstantPool(classFile* fp)
{
constants* info;
slots* pool;
u1* tags;
int i;
u1 type;
u2 len;
strconst* c;
char* uc;
u2 d2, d2b;
u4 d4;
int64 d8;
info = malloc(sizeof(constants));
if (info == 0) {
return (0);
}
readu2(&info->size, fp);
RDBG( printf("constant_pool_count=%d\n", info->size); )
/* Allocate space for tags and data */
pool = calloc((sizeof(slots) + sizeof(u1)) * info->size, sizeof(char));
if (pool == 0) {
return (0);
}
tags = (u1*)&pool[info->size];
info->data = pool;
info->tags = tags;
pool[0].v.taddr = 0;
tags[0] = CONSTANT_Unknown;
for (i = 1; i < info->size; i++) {
readu1(&type, fp);
RDBG( printf("Constant type %d\n", type); )
tags[i] = type;
if (type == CONSTANT_Utf8) {
readu2(&len, fp);
c = malloc(sizeof(strconst) + len + 1);
if (c == 0) {
return (0);
}
readm(c->data, len, sizeof(u1), fp);
c->data[len] = 0;
RDBG( printf("Utf8=%s\n", c->data); )
pool[i].v.taddr = addStringConstant(c);
}
else if (type == CONSTANT_Unicode) {
abort();
readu2(&len, fp);
uc = malloc(len * 2 + 1);
readm(uc, len, sizeof(u2), fp);
uc[len * 2] = 0;
abort();
}
else switch (type) {
case CONSTANT_Class:
readu2(&d2, fp);
pool[i].v.tint = d2;
break;
case CONSTANT_String:
readu2(&d2, fp);
pool[i].v.tint = d2;
tags[i] = CONSTANT_Chararray;
break;
case CONSTANT_Fieldref:
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref:
case CONSTANT_NameAndType:
readu2(&d2, fp);
readu2(&d2b, fp);
pool[i].v.tint = (d2b << 16) | d2;
break;
case CONSTANT_Integer:
case CONSTANT_Float:
readu4(&d4, fp);
pool[i].v.tint = d4;
break;
case CONSTANT_Long:
case CONSTANT_Double:
tags[i+1] = CONSTANT_Unknown;
pool[i+1].v.taddr = 0;
readu8(&d8, fp);
pool[i].v.tlong = d8;
i++;
break;
default:
fprintf(stderr, "Bad constant %d\n", type);
return (0);
}
}
/* Now create any string pairs required and any string objects */
for (i = 0; i < info->size; i++) {
if (tags[i] == CONSTANT_NameAndType) {
assert(tags[NAMEANDTYPE_NAME(i, info)] == CONSTANT_Utf8);
assert(tags[NAMEANDTYPE_SIGNATURE(i, info)] == CONSTANT_Utf8);
addStringConstantPair(pool[NAMEANDTYPE_NAME(i, info)].v.tstr, pool[NAMEANDTYPE_SIGNATURE(i, info)].v.tstr);
}
}
return (info);
}
/*
* Add a string to the string pool.
* If already there, free the new one and return the old one.
*/
char*
addStringConstant(strconst* s)
{
strconst* ptr;
uint32 hash;
int i;
for (hash = 0,i = 0; s->data[i] != 0; i++) {
hash = hash * 33 + s->data[i];
}
hash %= STRHASHSZ;
for (ptr = strhash[hash]; ptr != 0; ptr = ptr->next) {
if (ptr->data[0] == s->data[0] && strcmp(ptr->data, s->data) == 0) {
free(s);
return (ptr->data);
}
}
s->next = strhash[hash];
s->string = 0;
s->obj.dtable = (CharArrayClass != 0 ? CharArrayClass->dtable : 0);
INITGC(s->obj);
s->obj.size = i;
strhash[hash] = s;
return (s->data);
}
/*
* Add string pair to the pool.
*/
strpair*
addStringConstantPair(char* s1, char* s2)
{
uint32 hash;
int i;
strpair* ptr;
hash = 0;
for (i = 0; s1[i] != 0; i++) {
hash = hash * 33 + s1[i];
}
for (i = 0; s2[i] != 0; i++) {
hash = hash * 33 + s2[i];
}
for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
if (ptr->s1 == s1 && ptr->s2 == s2) {
return (ptr);
}
}
ptr = malloc(sizeof(strpair));
if (ptr == 0) {
return (0);
}
ptr->next = strpairhash[hash % STRHASHSZ];
ptr->hash = hash;
ptr->s1 = s1;
ptr->s2 = s2;
strpairhash[hash % STRHASHSZ] = ptr;
return (ptr);
}
/*
* Lookup a string pair in the pool.
*/
strpair*
lookupStringPair(char* s1, char* s2)
{
uint32 hash;
int i;
strpair* ptr;
hash = 0;
for (i = 0; s1[i] != 0; i++) {
hash = hash * 33 + s1[i];
}
for (i = 0; s2[i] != 0; i++) {
hash = hash * 33 + s2[i];
}
for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
if (ptr->s1 == s1 && ptr->s2 == s2) {
return (ptr);
}
}
return (0);
}