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 >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  243 lines

  1. /*
  2.  * constants.c
  3.  * Constant management.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
  12.  */
  13.  
  14. #define    RDBG(s)
  15.  
  16. #include "config.h"
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <assert.h>
  20. #include <string.h>
  21. #include "gtypes.h"
  22. #include "slots.h"
  23. #include "access.h"
  24. #include "object.h"
  25. #include "constants.h"
  26. #include "object.h"
  27. #include "classMethod.h"
  28. #include "file.h"
  29.  
  30. extern classes* CharArrayClass;
  31.  
  32. static strconst* strhash[STRHASHSZ];
  33. static strpair* strpairhash[STRHASHSZ];
  34.  
  35. /*
  36.  * Read in constant pool from opened file.
  37.  */
  38. constants*
  39. readConstantPool(classFile* fp)
  40. {
  41.     constants* info;
  42.     slots* pool;
  43.     u1* tags;
  44.     int i;
  45.     u1 type;
  46.     u2 len;
  47.     strconst* c;
  48.     char* uc;
  49.     u2 d2, d2b;
  50.     u4 d4;
  51.     int64 d8;
  52.  
  53.     info = malloc(sizeof(constants));
  54.     if (info == 0) {
  55.         return (0);
  56.     }
  57.  
  58.     readu2(&info->size, fp);
  59. RDBG(    printf("constant_pool_count=%d\n", info->size);    )
  60.  
  61.     /* Allocate space for tags and data */
  62.     pool = calloc((sizeof(slots) + sizeof(u1)) * info->size, sizeof(char));
  63.     if (pool == 0) {
  64.         return (0);
  65.     }
  66.     tags = (u1*)&pool[info->size];
  67.     info->data = pool;
  68.     info->tags = tags;
  69.  
  70.     pool[0].v.taddr = 0;
  71.     tags[0] = CONSTANT_Unknown;
  72.     for (i = 1; i < info->size; i++) {
  73.  
  74.         readu1(&type, fp);
  75. RDBG(        printf("Constant type %d\n", type);            )
  76.         tags[i] = type;
  77.  
  78.         if (type == CONSTANT_Utf8) {
  79.             readu2(&len, fp);
  80.             c = malloc(sizeof(strconst) + len + 1);
  81.             if (c == 0) {
  82.                 return (0);
  83.             }
  84.             readm(c->data, len, sizeof(u1), fp);
  85.             c->data[len] = 0;
  86. RDBG(            printf("Utf8=%s\n", c->data);            )
  87.  
  88.             pool[i].v.taddr = addStringConstant(c);
  89.         }
  90.         else if (type == CONSTANT_Unicode) {
  91.             abort();
  92.             readu2(&len, fp);
  93.             uc = malloc(len * 2 + 1);
  94.             readm(uc, len, sizeof(u2), fp);
  95.             uc[len * 2] = 0;
  96.             abort();
  97.         }
  98.         else switch (type) {
  99.         case CONSTANT_Class:
  100.             readu2(&d2, fp);
  101.             pool[i].v.tint = d2;
  102.             break;
  103.  
  104.         case CONSTANT_String:
  105.             readu2(&d2, fp);
  106.             pool[i].v.tint = d2;
  107.             tags[i] = CONSTANT_Chararray;
  108.             break;
  109.  
  110.         case CONSTANT_Fieldref:
  111.         case CONSTANT_Methodref:
  112.         case CONSTANT_InterfaceMethodref:
  113.         case CONSTANT_NameAndType:
  114.             readu2(&d2, fp);
  115.             readu2(&d2b, fp);
  116.             pool[i].v.tint = (d2b << 16) | d2;
  117.             break;
  118.  
  119.         case CONSTANT_Integer:
  120.         case CONSTANT_Float:
  121.             readu4(&d4, fp);
  122.             pool[i].v.tint = d4;
  123.             break;
  124.  
  125.         case CONSTANT_Long:
  126.         case CONSTANT_Double:
  127.             tags[i+1] = CONSTANT_Unknown;
  128.             pool[i+1].v.taddr = 0;
  129.             readu8(&d8, fp);
  130.             pool[i].v.tlong = d8;
  131.             i++;
  132.             break;
  133.  
  134.         default:
  135.             fprintf(stderr, "Bad constant %d\n", type);
  136.             return (0);
  137.         }
  138.     }
  139.  
  140.     /* Now create any string pairs required and any string objects */
  141.     for (i = 0; i < info->size; i++) {
  142.         if (tags[i] == CONSTANT_NameAndType) {
  143.             assert(tags[NAMEANDTYPE_NAME(i, info)] == CONSTANT_Utf8);
  144.             assert(tags[NAMEANDTYPE_SIGNATURE(i, info)] == CONSTANT_Utf8);
  145.             addStringConstantPair(pool[NAMEANDTYPE_NAME(i, info)].v.tstr, pool[NAMEANDTYPE_SIGNATURE(i, info)].v.tstr);
  146.         }
  147.     }
  148.  
  149.     return (info);
  150. }
  151.  
  152. /*
  153.  * Add a string to the string pool.
  154.  * If already there, free the new one and return the old one.
  155.  */
  156. char*
  157. addStringConstant(strconst* s)
  158. {
  159.     strconst* ptr;
  160.     uint32 hash;
  161.     int i;
  162.  
  163.     for (hash = 0,i = 0; s->data[i] != 0; i++) {
  164.         hash = hash * 33 + s->data[i];
  165.     }
  166.     hash %= STRHASHSZ;
  167.  
  168.     for (ptr = strhash[hash]; ptr != 0; ptr = ptr->next) {
  169.         if (ptr->data[0] == s->data[0] && strcmp(ptr->data, s->data) == 0) {
  170.             free(s);
  171.             return (ptr->data);
  172.         }
  173.     }
  174.     s->next = strhash[hash];
  175.     s->string = 0;
  176.     s->obj.dtable = (CharArrayClass != 0 ? CharArrayClass->dtable : 0);
  177.     INITGC(s->obj);
  178.     s->obj.size = i;
  179.     strhash[hash] = s;
  180.     return (s->data);
  181. }
  182.  
  183. /*
  184.  * Add string pair to the pool.
  185.  */
  186. strpair*
  187. addStringConstantPair(char* s1, char* s2)
  188. {
  189.     uint32 hash;
  190.     int i;
  191.     strpair* ptr;
  192.  
  193.     hash = 0;
  194.     for (i = 0; s1[i] != 0; i++) {
  195.         hash = hash * 33 + s1[i];
  196.     }
  197.     for (i = 0; s2[i] != 0; i++) {
  198.         hash = hash * 33 + s2[i];
  199.     }
  200.  
  201.     for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
  202.         if (ptr->s1 == s1 && ptr->s2 == s2) {
  203.             return (ptr);
  204.         }
  205.     }
  206.     ptr = malloc(sizeof(strpair));
  207.     if (ptr == 0) {
  208.         return (0);
  209.     }
  210.     ptr->next = strpairhash[hash % STRHASHSZ];
  211.     ptr->hash = hash;
  212.     ptr->s1 = s1;
  213.     ptr->s2 = s2;
  214.     strpairhash[hash % STRHASHSZ] = ptr;
  215.     return (ptr);
  216. }
  217.  
  218. /*
  219.  * Lookup a string pair in the pool.
  220.  */
  221. strpair*
  222. lookupStringPair(char* s1, char* s2)
  223. {
  224.     uint32 hash;
  225.     int i;
  226.     strpair* ptr;
  227.  
  228.     hash = 0;
  229.     for (i = 0; s1[i] != 0; i++) {
  230.         hash = hash * 33 + s1[i];
  231.     }
  232.     for (i = 0; s2[i] != 0; i++) {
  233.         hash = hash * 33 + s2[i];
  234.     }
  235.  
  236.     for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
  237.         if (ptr->s1 == s1 && ptr->s2 == s2) {
  238.             return (ptr);
  239.         }
  240.     }
  241.     return (0);
  242. }
  243.