home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / lookup.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-24  |  49.4 KB  |  1,815 lines

  1. // $Id: lookup.cpp,v 1.32 2001/02/17 08:08:54 mdejong Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "lookup.h"
  11. #include "control.h"
  12. #include "symbol.h"
  13. #include "code.h"
  14. #include "ast.h"
  15. #include "case.h"
  16.  
  17. #ifdef HAVE_RTTI
  18. #include <typeinfo>
  19. #endif
  20.  
  21. #ifdef    HAVE_JIKES_NAMESPACE
  22. namespace Jikes {    // Open namespace Jikes block
  23. #endif
  24.  
  25. int SystemTable::primes[] = {DEFAULT_HASH_SIZE, 101, 401, MAX_HASH_SIZE};
  26.  
  27. SystemTable::SystemTable(int hash_size_) : directories(1024)
  28. {
  29.     hash_size = (hash_size_ <= 0 ? 1 : hash_size_);
  30.  
  31.     prime_index = -1;
  32.     do
  33.     {
  34.         if (hash_size < primes[prime_index + 1])
  35.             break;
  36.         prime_index++;
  37.     } while (primes[prime_index] < MAX_HASH_SIZE);
  38.  
  39.     base = (Element **) memset(new Element *[hash_size], 0, hash_size * sizeof(Element *));
  40. }
  41.  
  42. SystemTable::~SystemTable()
  43. {
  44.     for (int i = 0; i < directories.Length(); i++)
  45.         delete directories[i];
  46.  
  47.     delete [] base;
  48. }
  49.  
  50. void SystemTable::Rehash()
  51. {
  52.     hash_size = primes[++prime_index];
  53.  
  54.     delete [] base;
  55.     base = (Element **) memset(new Element *[hash_size], 0, hash_size * sizeof(Element *));
  56.  
  57.     for (int k = 0; k < directories.Length(); k++)
  58.     {
  59.         Element *element = directories[k];
  60.  
  61.         int i = hash(element -> device, element -> inode);
  62.         element -> next = base[i];
  63.         base[i] = element;
  64.     }
  65.  
  66.     return;
  67. }
  68.  
  69. DirectorySymbol *SystemTable::FindDirectorySymbol(dev_t device, ino_t inode)
  70. {
  71.     int k = hash(device, inode);
  72.  
  73.     for (Element *element = base[k]; element; element = element -> next)
  74.     {
  75.         if (element -> device == device && element -> inode == inode)
  76.             return element -> directory_symbol;
  77.     }
  78.  
  79.     return NULL;
  80. }
  81.  
  82. void SystemTable::InsertDirectorySymbol(dev_t device, ino_t inode, DirectorySymbol *directory_symbol)
  83. {
  84.     int k = hash(device, inode);
  85.  
  86.     Element *element = new Element(device, inode, directory_symbol);
  87.     directories.Next() = element;
  88.  
  89.     element -> next = base[k];
  90.     base[k] = element;
  91.  
  92.     //
  93.     // If the set is "adjustable" and the number of unique elements in it exceeds
  94.     // 2 times the size of the base, and we have not yet reached the maximum
  95.     // allowable size for a base, reallocate a larger base and rehash the elements.
  96.     //
  97.     if ((directories.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  98.         Rehash();
  99.  
  100.     return;
  101. }
  102.  
  103. int DirectoryTable::primes[] = {DEFAULT_HASH_SIZE, 2039, 4093, MAX_HASH_SIZE};
  104.  
  105. DirectoryTable::DirectoryTable(int estimate) : entry_pool(estimate),
  106.                                                hash_size(primes[0]),
  107.                                                prime_index(0)
  108. {
  109.     base = (DirectoryEntry **) memset(new DirectoryEntry *[hash_size], 0, hash_size * sizeof(DirectoryEntry *));
  110. }
  111.  
  112. DirectoryTable::~DirectoryTable()
  113. {
  114. /*
  115. int n;
  116. int num_slots = 0;
  117. int total = 0;
  118. for (n = 0; n < hash_size; n++)
  119. {
  120. int num = 0;
  121. for (Symbol *s = base[n]; s; s = s -> next)
  122.     num++;
  123. if (num > 0)
  124. {
  125. num_slots++;
  126. total += num;
  127. }
  128. }
  129.  
  130. if (num_slots > 0)
  131. {
  132. Coutput << "\nDestroying the Name table with " << total
  133.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  134. for (n = 0; n < hash_size; n++)
  135. {
  136. int num = 0;
  137. for (Symbol *s = base[n]; s; s = s -> next)
  138.     num++;
  139. if (num > 0)
  140. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  141. }
  142. }
  143. if (hash_size < total)
  144.     total = total;
  145. */
  146.     for (int i = 0; i < entry_pool.Length(); i++)
  147.         delete entry_pool[i];
  148.     delete [] base;
  149. }
  150.  
  151.  
  152. DirectoryEntry *DirectoryTable::FindEntry(char *str, int len)
  153. {
  154.     int k = Hash(str, len) % hash_size;
  155.     DirectoryEntry *entry;
  156.     for (entry = base[k]; entry; entry = entry -> next)
  157.     {
  158.         if (len == entry -> length && memcmp(entry -> name, str, len * sizeof(char)) == 0)
  159.             return (entry -> IsDummy() ? (DirectoryEntry *) NULL : entry);
  160.     }
  161.  
  162.     return NULL;
  163. }
  164.  
  165.  
  166. void DirectoryTable::Rehash()
  167. {
  168.     hash_size = primes[++prime_index];
  169.  
  170.     delete [] base;
  171.     base = (DirectoryEntry **) memset(new DirectoryEntry *[hash_size], 0, hash_size * sizeof(DirectoryEntry *));
  172.  
  173.     for (int i = 0; i < entry_pool.Length(); i++)
  174.     {
  175.         DirectoryEntry *e = entry_pool[i];
  176.         int k = Hash(e -> name, e -> length) % hash_size;
  177.         e -> next = base[k];
  178.         base[k] = e;
  179.     }
  180.  
  181.     return;
  182. }
  183.  
  184.  
  185. DirectoryEntry *DirectoryTable::InsertEntry(DirectorySymbol *directory_symbol, char *str, int len)
  186. {
  187.     int k = Hash(str, len) % hash_size;
  188.     DirectoryEntry *entry;
  189.     for (entry = base[k]; entry; entry = entry -> next)
  190.     {
  191.         if (len == entry -> length && memcmp(entry -> name, str, len * sizeof(char)) == 0)
  192.             return entry;
  193.     }
  194.  
  195.     entry = new DirectoryEntry();
  196.     entry_pool.Next() = entry;
  197.     entry -> Initialize(directory_symbol, str, len);
  198.  
  199.     entry -> next = base[k];
  200.     base[k] = entry;
  201.  
  202.     //
  203.     // If the number of unique elements in the hash table exceeds 2 times
  204.     // the size of the base, and we have not yet reached the maximum
  205.     // allowable size for a base, reallocate a larger base and rehash
  206.     // the elements.
  207.     //
  208.     if ((entry_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  209.         Rehash();
  210.  
  211.     return entry;
  212. }
  213.  
  214.  
  215. #ifdef WIN32_FILE_SYSTEM
  216. DirectoryEntry *DirectoryTable::FindCaseInsensitiveEntry(char *name, int length)
  217. {
  218.     char *lower_name = new char[length + 1];
  219.     for (int i = 0; i < length; i++)
  220.         lower_name[i] = Case::ToAsciiLower(name[i]);
  221.     lower_name[length] = U_NULL;
  222.  
  223.     DirectoryEntry *entry = FindEntry(lower_name, length);
  224.     delete [] lower_name;
  225.  
  226.     return (entry ? entry -> Image() : entry);
  227. }
  228.  
  229. void DirectoryTable::InsertCaseInsensitiveEntry(DirectoryEntry *image)
  230. {
  231.     int length = image -> length;
  232.     char *lower_name = new char[length + 1];
  233.     for (int i = 0; i < length; i++)
  234.         lower_name[i] = Case::ToAsciiLower(image -> name[i]);
  235.     lower_name[length] = U_NULL;
  236.  
  237.     int k = Hash(lower_name, length) % hash_size;
  238.     DirectoryEntry *entry;
  239.     for (entry = base[k]; entry; entry = entry -> next)
  240.     {
  241.         if (length == entry -> length && memcmp(entry -> name, lower_name, length * sizeof(char)) == 0)
  242.             break;
  243.     }
  244.  
  245.     if (! entry)
  246.     {
  247.         FoldedDirectoryEntry *folded_entry = new FoldedDirectoryEntry(image);
  248.         entry_pool.Next() = folded_entry;
  249.         folded_entry -> Initialize(image, lower_name, length);
  250.  
  251.         folded_entry -> next = base[k];
  252.         base[k] = folded_entry;
  253.  
  254.         //
  255.         // If the number of unique elements in the hash table exceeds 2 times
  256.         // the size of the base, and we have not yet reached the maximum
  257.         // allowable size for a base, reallocate a larger base and rehash
  258.         // the elements.
  259.         //
  260.         if ((entry_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  261.             Rehash();
  262.     }
  263.  
  264.     delete [] lower_name;
  265.  
  266.     return;
  267. }
  268. #endif
  269.  
  270.  
  271. time_t DirectoryEntry::Mtime()
  272. {
  273.     if (mtime_ == 0)
  274.     {
  275.         char *dirname = this -> directory -> DirectoryName();
  276.         int length = this -> directory -> DirectoryNameLength() + this -> length + 1; // +1 for '/'
  277.         char *file_name = new char[length + 1];
  278.         strcpy(file_name, dirname);
  279.         if (dirname[this -> directory -> DirectoryNameLength() - 1] != U_SLASH)
  280.             strcat(file_name, StringConstant::U8S__SL);
  281.         strcat(file_name, this -> name);
  282.  
  283.         struct stat status;
  284.         if (JikesAPI::getInstance()->stat(file_name, &status) == 0)
  285.              mtime_ = status.st_mtime;
  286.         else assert(false && "Cannot compute system time stamp\n");
  287.  
  288.         delete [] file_name;
  289.     }
  290.  
  291.     return mtime_;
  292. }
  293.  
  294.  
  295. int NameLookupTable::primes[] = {DEFAULT_HASH_SIZE, 8191, 16411, MAX_HASH_SIZE};
  296.  
  297. NameLookupTable::NameLookupTable(int estimate) : symbol_pool(estimate),
  298.                                                  hash_size(primes[0]),
  299.                                                  prime_index(0)
  300. {
  301.     base = (NameSymbol **) memset(new NameSymbol *[hash_size], 0, hash_size * sizeof(NameSymbol *));
  302. }
  303.  
  304. NameLookupTable::~NameLookupTable()
  305. {
  306. /*
  307. int n;
  308. int num_slots = 0;
  309. int total = 0;
  310. for (n = 0; n < hash_size; n++)
  311. {
  312. int num = 0;
  313. for (Symbol *s = base[n]; s; s = s -> next)
  314.     num++;
  315. if (num > 0)
  316. {
  317. num_slots++;
  318. total += num;
  319. }
  320. }
  321.  
  322. if (num_slots > 0)
  323. {
  324. Coutput << "\nDestroying the Name table with " << total
  325.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  326. for (n = 0; n < hash_size; n++)
  327. {
  328. int num = 0;
  329. for (Symbol *s = base[n]; s; s = s -> next)
  330.     num++;
  331. if (num > 0)
  332. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  333. }
  334. }
  335. if (hash_size < total)
  336.     total = total;
  337. */
  338.     for (int i = 0; i < symbol_pool.Length(); i++)
  339.         delete symbol_pool[i];
  340.     delete [] base;
  341. }
  342.  
  343.  
  344. void NameLookupTable::Rehash()
  345. {
  346.     hash_size = primes[++prime_index];
  347.  
  348.     delete [] base;
  349.     base = (NameSymbol **) memset(new NameSymbol *[hash_size], 0, hash_size * sizeof(NameSymbol *));
  350.  
  351.     for (int i = 0; i < symbol_pool.Length(); i++)
  352.     {
  353.         NameSymbol *ns = symbol_pool[i];
  354.         int k = ns -> hash_address % hash_size;
  355.         ns -> next = base[k];
  356.         base[k] = ns;
  357.     }
  358.  
  359.     return;
  360. }
  361.  
  362.  
  363. NameSymbol *NameLookupTable::FindOrInsertName(wchar_t *str, size_t len)
  364. {
  365.     unsigned hash_address = Hash(str, len);
  366.     int k = hash_address % hash_size;
  367.     NameSymbol *symbol;
  368.     for (symbol = base[k]; symbol; symbol = (NameSymbol *) symbol -> next)
  369.     {
  370.         if (len == symbol -> NameLength() && memcmp(symbol -> Name(), str, len * sizeof(wchar_t)) == 0)
  371.             return symbol;
  372.     }
  373.  
  374.     int index = symbol_pool.Length(); // index of the next element
  375.     symbol = new NameSymbol();
  376.     symbol_pool.Next() = symbol;
  377.     symbol -> Initialize(str, len, hash_address, index);
  378.  
  379.     symbol -> next = base[k];
  380.     base[k] = symbol;
  381.  
  382.     //
  383.     // If the number of unique elements in the hash table exceeds 2 times
  384.     // the size of the base, and we have not yet reached the maximum
  385.     // allowable size for a base, reallocate a larger base and rehash
  386.     // the elements.
  387.     //
  388.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  389.         Rehash();
  390.  
  391.     return symbol;
  392. }
  393.  
  394.  
  395. int TypeLookupTable::primes[] = {DEFAULT_HASH_SIZE, 8191, 16411, MAX_HASH_SIZE};
  396.  
  397. TypeLookupTable::TypeLookupTable(int estimate) : symbol_pool(estimate),
  398.                                                  hash_size(primes[0]),
  399.                                                  prime_index(0)
  400. {
  401.     base = (TypeSymbol **) memset(new TypeSymbol *[hash_size], 0, hash_size * sizeof(TypeSymbol *));
  402. }
  403.  
  404.  
  405. TypeLookupTable::~TypeLookupTable()
  406. {
  407. /*
  408. int n;
  409. int num_slots = 0;
  410. int total = 0;
  411. for (n = 0; n < hash_size; n++)
  412. {
  413. int num = 0;
  414. for (TypeSymbol *s = base[n]; s; s = s -> next_type)
  415.     num++;
  416. if (num > 0)
  417. {
  418. num_slots++;
  419. total += num;
  420. }
  421. }
  422.  
  423. if (num_slots > 0)
  424. {
  425. Coutput << "\nDestroying the Type table with " << total
  426.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  427. for (n = 0; n < hash_size; n++)
  428. {
  429. int num = 0;
  430. for (TypeSymbol *s = base[n]; s; s = s -> next_type)
  431.     num++;
  432. if (num > 0)
  433. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  434. }
  435. }
  436. if (hash_size < total)
  437.     total = total;
  438. */
  439.  
  440.     delete [] base;
  441. }
  442.  
  443.  
  444. void TypeLookupTable::Rehash()
  445. {
  446.     hash_size = primes[++prime_index];
  447.  
  448.     delete [] base;
  449.     base = (TypeSymbol **) memset(new TypeSymbol *[hash_size], 0, hash_size * sizeof(TypeSymbol *));
  450.  
  451.     for (int i = 0; i < symbol_pool.Length(); i++)
  452.     {
  453.         TypeSymbol *type = symbol_pool[i];
  454.         int k = type -> hash_address % hash_size;
  455.         type -> next_type = base[k];
  456.         base[k] = type;
  457.     }
  458.  
  459.     return;
  460. }
  461.  
  462.  
  463. TypeSymbol *TypeLookupTable::FindType(const char *str, int len)
  464. {
  465.     unsigned hash_address = Hash(str, len);
  466.     int k = hash_address % hash_size;
  467.  
  468.     for (TypeSymbol *type = base[k]; type; type = type -> next_type)
  469.     {
  470.         assert(type -> fully_qualified_name);
  471.  
  472.         Utf8LiteralValue *fully_qualified_name = type -> fully_qualified_name;
  473.         if (len == fully_qualified_name -> length && memcmp(fully_qualified_name -> value, str, len * sizeof(char)) == 0)
  474.             return type;
  475.     }
  476.  
  477.     return NULL;
  478. }
  479.  
  480.  
  481. void TypeLookupTable::InsertType(TypeSymbol *type)
  482. {
  483.     assert(type && type -> fully_qualified_name);
  484.  
  485.     unsigned hash_address = Hash(type -> fully_qualified_name -> value, type -> fully_qualified_name -> length);
  486.     int k = hash_address % hash_size;
  487.  
  488. #ifdef JIKES_DEBUG
  489.     for (TypeSymbol *t = base[k]; t; t = t -> next_type)
  490.         assert (type != t && "Type was already entered in type table");
  491. #endif
  492.  
  493.     symbol_pool.Next() = type;
  494.     type -> hash_address = hash_address;
  495.  
  496.     type -> next_type = base[k];
  497.     base[k] = type;
  498.  
  499.     //
  500.     // If the number of unique elements in the hash table exceeds 2 times
  501.     // the size of the base, and we have not yet reached the maximum
  502.     // allowable size for a base, reallocate a larger base and rehash
  503.     // the elements.
  504.     //
  505.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  506.         Rehash();
  507.  
  508.     return;
  509. }
  510.  
  511.  
  512. //
  513. // Remove all elements from the table.
  514. //
  515. void TypeLookupTable::SetEmpty()
  516. {
  517.     symbol_pool.Reset();
  518.     (void) memset(base, 0, hash_size * sizeof(TypeSymbol *));
  519. }
  520.  
  521.  
  522. int IntLiteralTable::int32_limit = 0x7FFFFFFF / 10;
  523. int IntLiteralTable::primes[] = {DEFAULT_HASH_SIZE, 8191, 16411, MAX_HASH_SIZE};
  524.  
  525. IntLiteralTable::IntLiteralTable(LiteralValue *bad_value_) : symbol_pool(16384),
  526.                                                              hash_size(primes[0]),
  527.                                                              prime_index(0),
  528.                                                              bad_value(bad_value_)
  529. {
  530.     base = (IntLiteralValue **) memset(new IntLiteralValue *[hash_size], 0, hash_size * sizeof(IntLiteralValue *));
  531.     symbol_pool.Next() = NULL; // do not use the 0th element
  532. }
  533.  
  534. IntLiteralTable::~IntLiteralTable()
  535. {
  536. /*
  537. int n;
  538. int num_slots = 0;
  539. int total = 0;
  540. for (n = 0; n < hash_size; n++)
  541. {
  542. int num = 0;
  543. for (LiteralValue *s = base[n]; s; s = s -> next)
  544.     num++;
  545. if (num > 0)
  546. {
  547. num_slots++;
  548. total += num;
  549. }
  550. }
  551.  
  552. if (num_slots > 0)
  553. {
  554. Coutput << "\nDestroying the integer table with " << total
  555.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  556. for (n = 0; n < hash_size; n++)
  557. {
  558. int num = 0;
  559. for (LiteralValue *s = base[n]; s; s = s -> next)
  560.     num++;
  561. if (num > 0)
  562. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  563. }
  564. }
  565. if (hash_size < total)
  566.     total = total;
  567. */
  568.  
  569.     for (int i = 0; i < symbol_pool.Length(); i++)
  570.         delete symbol_pool[i];
  571.     delete [] base;
  572. }
  573.  
  574.  
  575. LiteralValue *IntLiteralTable::FindOrInsertChar(LiteralSymbol *literal)
  576. {
  577.     wchar_t *name = literal -> Name();
  578.  
  579.     if (literal -> NameLength() == 1) // an isolated quote
  580.          return literal -> value = bad_value;
  581.     else if (literal -> NameLength() <= 3) // a regular character of the form:  quote + char
  582.                                            // or                                quote + char + quote
  583.          return literal -> value = FindOrInsert((int) name[1]);
  584.  
  585.     int value;
  586.  
  587.     if (name[1] != U_BACKSLASH)
  588.          value = -1;
  589.     else if (name[2] == U_b && name[3] == U_SINGLE_QUOTE)
  590.          value = U_BACKSPACE;
  591.     else if (name[2] == U_t && name[3] == U_SINGLE_QUOTE)
  592.          value = U_HORIZONTAL_TAB;
  593.     else if (name[2] == U_n && name[3] == U_SINGLE_QUOTE)
  594.          value = U_LINE_FEED;
  595.     else if (name[2] == U_f && name[3] == U_SINGLE_QUOTE)
  596.          value = U_FORM_FEED;
  597.     else if (name[2] == U_r && name[3] == U_SINGLE_QUOTE)
  598.          value = U_CARRIAGE_RETURN;
  599.     else if (name[2] == U_DOUBLE_QUOTE && name[3] == U_SINGLE_QUOTE)
  600.          value = U_DOUBLE_QUOTE;
  601.     else if (name[2] == U_SINGLE_QUOTE && name[3] == U_SINGLE_QUOTE)
  602.          value = U_SINGLE_QUOTE;
  603.     else if (name[2] == U_BACKSLASH && name[3] == U_SINGLE_QUOTE)
  604.          value = U_BACKSLASH;
  605.     else if (Code::IsDigit(name[2]))
  606.     {
  607.         wchar_t *p = &name[2];
  608.  
  609.         int d1 = *p++ - U_0;
  610.         value = (d1 < 8 ? d1 : -1);
  611.  
  612.         if (value >= 0 && Code::IsDigit(*p))
  613.         {
  614.             int d2 = *p++ - U_0;
  615.             value = (d2 < 8 ? value * 8 + d2 : -1);
  616.  
  617.             if (value >= 0 && Code::IsDigit(*p))
  618.             {
  619.                 int d3 = *p++ - U_0;
  620.                 value = (d3 < 8 && d1 < 4 ? value * 8 + d3 : -1);
  621.             }
  622.         }
  623.  
  624.         if (*p != U_NULL && *p != U_SINGLE_QUOTE)
  625.             value = -1;
  626.     }
  627.     else value = -1;
  628.  
  629.     return literal -> value = (value < 0 || value > 65535 ? bad_value : FindOrInsert(value));
  630. }
  631.  
  632.  
  633. LiteralValue *IntLiteralTable::FindOrInsertHexInt(LiteralSymbol *literal)
  634. {
  635.     wchar_t *head = literal -> Name() + 1, // point to X
  636.             *tail = &literal -> Name()[literal -> NameLength() - 1];
  637.  
  638.     u4 uvalue = 0;
  639.  
  640.     //
  641.     // According to the JLS 3.10.1, "A compile-time error occurs if ... a
  642.     // hexadecimal or octal int literal does not fit in 32 bits".
  643.     // So, strictly speaking, we should not skip leading zeroes. However,
  644.     // there are many publicly available code out there with leading zeroes
  645.     // that don't compile with jikes, if ...
  646.     //
  647.     {
  648.         for (++head; tail > head && *head == U_0; head++) // skip leading zeroes
  649.             ;
  650.         head--;
  651.     }
  652.  
  653.     for (int i = 0; i < 32 && tail > head; i += 4, tail--)
  654.     {
  655.         u4 d = *tail - (Code::IsDigit(*tail) ? U_0 : (Code::IsLower(*tail) ? U_a : U_A) - 10);
  656.         uvalue |= (d << i);
  657.     }
  658.  
  659.     return (tail > head ? bad_value : FindOrInsert((int) uvalue));
  660. }
  661.  
  662.  
  663. LiteralValue *IntLiteralTable::FindOrInsertOctalInt(LiteralSymbol *literal)
  664. {
  665.     wchar_t *head = literal -> Name(), // point to initial '0'
  666.             *tail = &head[literal -> NameLength() - 1];
  667.  
  668.     u4 uvalue = 0;
  669.     //
  670.     // According to the JLS 3.10.1, "A compile-time error occurs if ... a
  671.     // hexadecimal or octal int literal does not fit in 32 bits".
  672.     // So, strictly speaking, we should not skip leading zeroes. However,
  673.     // there are many publicly available code out there with leading zeroes
  674.     // that don't compile with jikes,...
  675.     //
  676.     {
  677.         for (++head; tail > head && *head == U_0; head++) // skip leading zeroes
  678.             ;
  679.         head--;
  680.     }
  681.  
  682.     for (int i = 0; i < 30 && tail > head; i += 3, tail--)
  683.     {
  684.         u4 d = *tail - U_0;
  685.         uvalue |= (d << i);
  686.     }
  687.  
  688.     if (tail > head)
  689.     {
  690.         u4 d = *tail - U_0;
  691.  
  692.         if (d <= 3) // max number that can fit in 2 bits
  693.         {
  694.             tail--;
  695.             uvalue |= (d << 30);
  696.         }
  697.     }
  698.  
  699.     return (tail > head ? bad_value : FindOrInsert((int) uvalue));
  700. }
  701.  
  702.  
  703. LiteralValue *IntLiteralTable::FindOrInsertInt(LiteralSymbol *literal)
  704. {
  705.     wchar_t *name = literal -> Name();
  706.  
  707.     if (name[0] == U_0)
  708.         literal -> value = (name[1] == U_x || name[1] == U_X ? FindOrInsertHexInt(literal) : FindOrInsertOctalInt(literal));
  709.     else
  710.     {
  711.         int value = 0;
  712.  
  713.         wchar_t *p;
  714.         for (p = name; *p; p++)
  715.         {
  716.             int digit = *p - U_0;
  717.             if (value > int32_limit || (value == int32_limit && digit > 7))
  718.                 break;
  719.             value = value * 10 + digit;
  720.         }
  721.  
  722.         literal -> value = (*p ? bad_value : FindOrInsert(value));
  723.     }
  724.  
  725.     return literal -> value;
  726. }
  727.  
  728.  
  729. LiteralValue *IntLiteralTable::FindOrInsertNegativeInt(LiteralSymbol *literal)
  730. {
  731.     if (literal -> value && literal -> value != bad_value) // a positive value already exists
  732.     {
  733.         IntLiteralValue *int_literal = (IntLiteralValue *) literal -> value;
  734.         return FindOrInsert(- int_literal -> value);
  735.     }
  736.  
  737.     wchar_t *name = literal -> Name();
  738.  
  739.     //
  740.     // We can assert that the name of a literal contains at least two characters:
  741.     // at least one digit and the terminating '\0'.
  742.     //
  743.     if (name[0] == U_0)
  744.     {
  745.         IntLiteralValue *int_literal = (IntLiteralValue *) (name[1] == U_x || name[1] == U_X
  746.                                                                      ? FindOrInsertHexInt(literal)
  747.                                                                      : FindOrInsertOctalInt(literal));
  748.         return FindOrInsert(- int_literal -> value);
  749.     }
  750.  
  751.     int value = 0;
  752.  
  753.     wchar_t *p;
  754.     for (p = name; *p; p++)
  755.     {
  756.         int digit = *p - U_0;
  757.         if (value > int32_limit || (value == int32_limit && digit > 8))
  758.             break;
  759.         value = value * 10 + digit;
  760.     }
  761.  
  762.     return (*p ? bad_value : FindOrInsert(-value));
  763. }
  764.  
  765.  
  766. void IntLiteralTable::Rehash()
  767. {
  768.     hash_size = primes[++prime_index];
  769.  
  770.     delete [] base;
  771.     base = (IntLiteralValue **) memset(new IntLiteralValue *[hash_size], 0, hash_size * sizeof(IntLiteralValue *));
  772.  
  773.     //
  774.     // Recall that the 0th element is unused.
  775.     //
  776.     for (int i = 1; i < symbol_pool.Length(); i++)
  777.     {
  778.         IntLiteralValue *ilv = symbol_pool[i];
  779.         int k = ((unsigned) ilv -> value) % hash_size; // The unsigned casting turns the negative values into positive values
  780.         ilv -> next = base[k];
  781.         base[k] = ilv;
  782.     }
  783.  
  784.     return;
  785. }
  786.  
  787.  
  788. IntLiteralValue *IntLiteralTable::Find(int value)
  789. {
  790.     int k = ((unsigned) value) % hash_size; // The unsigned casting turns the negative values into positive values
  791.  
  792.     IntLiteralValue *lit = NULL;
  793.     for (lit = base[k]; lit; lit = (IntLiteralValue *) lit -> next)
  794.     {
  795.         if (lit -> value == value)
  796.             break;
  797.     }
  798.  
  799.     return lit;
  800. }
  801.  
  802.  
  803. IntLiteralValue *IntLiteralTable::FindOrInsert(int value)
  804. {
  805.     int k = ((unsigned) value) % hash_size; // The unsigned casting turns the negative values into positive values
  806.  
  807.     IntLiteralValue *lit;
  808.     for (lit = base[k]; lit; lit = (IntLiteralValue *) lit -> next)
  809.     {
  810.         if (lit -> value == value)
  811.             return lit;
  812.     }
  813.  
  814.     lit = new IntLiteralValue();
  815.     lit -> Initialize(value, symbol_pool.Length());
  816.     symbol_pool.Next() = lit;
  817.  
  818.     lit -> next = base[k];
  819.     base[k] = lit;
  820.  
  821.     //
  822.     // If the number of unique elements in the hash table exceeds 2 times
  823.     // the size of the base, and we have not yet reached the maximum
  824.     // allowable size for a base, reallocate a larger base and rehash
  825.     // the elements.
  826.     //
  827.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  828.         Rehash();
  829.  
  830.     return lit;
  831. }
  832.  
  833.  
  834. LongInt LongLiteralTable::int64_limit = LongInt(0x7FFFFFFF, 0xFFFFFFFF) / 10;
  835. int LongLiteralTable::primes[] = {DEFAULT_HASH_SIZE, 2039, 4093, MAX_HASH_SIZE};
  836.  
  837. LongLiteralTable::LongLiteralTable(LiteralValue *bad_value_) : symbol_pool(16384),
  838.                                                                hash_size(primes[0]),
  839.                                                                prime_index(0),
  840.                                                                bad_value(bad_value_)
  841. {
  842.     base = (LongLiteralValue **) memset(new LongLiteralValue *[hash_size], 0, hash_size * sizeof(LongLiteralValue *));
  843.     symbol_pool.Next() = NULL; // do not use the 0th element
  844. }
  845.  
  846. LongLiteralTable::~LongLiteralTable()
  847. {
  848. /*
  849. int n;
  850. int num_slots = 0;
  851. int total = 0;
  852. for (n = 0; n < hash_size; n++)
  853. {
  854. int num = 0;
  855. for (LiteralValue *s = base[n]; s; s = s -> next)
  856.     num++;
  857. if (num > 0)
  858. {
  859. num_slots++;
  860. total += num;
  861. }
  862. }
  863.  
  864. if (num_slots > 0)
  865. {
  866. Coutput << "\nDestroying the long table with " << total
  867.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  868. for (n = 0; n < hash_size; n++)
  869. {
  870. int num = 0;
  871. for (LiteralValue *s = base[n]; s; s = s -> next)
  872.     num++;
  873. if (num > 0)
  874. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  875. }
  876. }
  877. if (hash_size < total)
  878.     total = total;
  879. */
  880.  
  881.     for (int i = 0; i < symbol_pool.Length(); i++)
  882.         delete symbol_pool[i];
  883.     delete [] base;
  884. }
  885.  
  886.  
  887. LiteralValue *LongLiteralTable::FindOrInsertHexLong(LiteralSymbol *literal)
  888. {
  889.     u4 high = 0,
  890.        low = 0;
  891.  
  892.     wchar_t *head = literal -> Name() + 1, // point to X
  893.             *tail = &literal -> Name()[literal -> NameLength() - 2]; // -2 to skip the 'L' suffix
  894.  
  895.     //
  896.     // According to the JLS 3.10.1, "A compile-time error occurs if ... a
  897.     // hexadecimal or octal int literal does not fit in 32 bits".
  898.     // So, strictly speaking, we should not skip leading zeroes. However,
  899.     // there are many publicly available code out there with leading zeroes
  900.     // that don't compile with jikes,...
  901.     //
  902.     {
  903.         for (++head; tail > head && *head == U_0; head++) // skip leading zeroes
  904.             ;
  905.         head--;
  906.     }
  907.  
  908.     for (int i = 0; i < 32 && tail > head; i += 4, tail--)
  909.     {
  910.         u4 d = *tail - (Code::IsDigit(*tail) ? U_0 : (Code::IsLower(*tail) ? U_a : U_A) - 10);
  911.         low |= (d << i);
  912.     }
  913.  
  914.     for (int j = 0; j < 32 && tail > head; j += 4, tail--)
  915.     {
  916.         u4 d = *tail - (Code::IsDigit(*tail) ? U_0 : (Code::IsLower(*tail) ? U_a : U_A) - 10);
  917.         high |= (d << j);
  918.     }
  919.  
  920.     return (tail > head ? bad_value : FindOrInsert(LongInt(high, low)));
  921. }
  922.  
  923.  
  924. LiteralValue *LongLiteralTable::FindOrInsertOctalLong(LiteralSymbol *literal)
  925. {
  926.     wchar_t *head = literal -> Name(), // point to initial '0'
  927.             *tail = &head[literal -> NameLength() - 2]; // -2 to skip the 'L' suffix
  928.  
  929.     ULongInt uvalue = 0;
  930.     //
  931.     // According to the JLS 3.10.1, "A compile-time error occurs if ... a
  932.     // hexadecimal or octal int literal does not fit in 32 bits".
  933.     // So, strictly speaking, we should not skip leading zeroes. However,
  934.     // there are many publicly available code out there with leading zeroes
  935.     // that wouldn't otherwise compile with jikes,...
  936.     //
  937.     {
  938.         for (++head; tail > head && *head == U_0; head++) // skip leading zeroes
  939.             ;
  940.         head--;
  941.     }
  942.  
  943.     for (int i = 0; i < 63 && tail > head; i += 3, tail--)
  944.     {
  945.         ULongInt d = (u4) (*tail - U_0);
  946.         uvalue |= (d << i);
  947.     }
  948.  
  949.     if (tail > head)
  950.     {
  951.         u4 d = *tail - U_0;
  952.  
  953.         if (d <= 1) // max number that can fit in 1 bit
  954.         {
  955.             tail--;
  956.             uvalue |= ULongInt((d << 31), 0);
  957.         }
  958.     }
  959.  
  960.     return (tail > head ? bad_value : FindOrInsert((LongInt) uvalue));
  961. }
  962.  
  963.  
  964. LiteralValue *LongLiteralTable::FindOrInsertLong(LiteralSymbol *literal)
  965. {
  966.     wchar_t *name = literal -> Name();
  967.  
  968.     //
  969.     // We can assert that the name of a literal contains at least two characters:
  970.     // at least one digit and the terminating '\0'.
  971.     //
  972.     if (name[0] == U_0)
  973.         literal -> value = (name[1] == U_x || name[1] == U_X ? FindOrInsertHexLong(literal) : FindOrInsertOctalLong(literal));
  974.     else
  975.     {
  976.         LongInt value = 0;
  977.  
  978.         wchar_t *p;
  979.         for (p = name; *p != U_L && *p != U_l; p++)
  980.         {
  981.             u4 digit = *p - U_0;
  982.             if (value > int64_limit || (value == int64_limit && digit > 7))
  983.                 break;
  984.             value = value * 10 + digit;
  985.         }
  986.  
  987.         literal -> value = (*p != U_L && *p != U_l ? bad_value : FindOrInsert(value));
  988.     }
  989.  
  990.     return literal -> value;
  991. }
  992.  
  993.  
  994. LiteralValue *LongLiteralTable::FindOrInsertNegativeLong(LiteralSymbol *literal)
  995. {
  996.     if (literal -> value && literal -> value != bad_value) // a positive value already exists
  997.     {
  998.         LongLiteralValue *long_literal = (LongLiteralValue *) literal -> value;
  999.         return FindOrInsert(- long_literal -> value);
  1000.     }
  1001.  
  1002.     wchar_t *name = literal -> Name();
  1003.     //
  1004.     // We can assert that the name of a literal contains at least two characters:
  1005.     // at least one digit and the terminating '\0'.
  1006.     //
  1007.     if (name[0] == U_0)
  1008.     {
  1009.         LongLiteralValue *long_literal = (LongLiteralValue *) (name[1] == U_x || name[1] == U_X
  1010.                                                                                ? FindOrInsertHexLong(literal)
  1011.                                                                                : FindOrInsertOctalLong(literal));
  1012.         return FindOrInsert(- long_literal -> value);
  1013.     }
  1014.  
  1015.     LongInt value = 0;
  1016.  
  1017.     wchar_t *p;
  1018.     for (p = name; *p != U_L && *p != U_l && value >= 0; p++)
  1019.     {
  1020.         u4 digit = *p - U_0;
  1021.         if (value > int64_limit || (value == int64_limit && digit > 8))
  1022.             break;
  1023.         value = value * 10 + digit;
  1024.     }
  1025.  
  1026.     return (*p != U_L && *p != U_l ? bad_value : FindOrInsert(-value));
  1027. }
  1028.  
  1029.  
  1030. void LongLiteralTable::Rehash()
  1031. {
  1032.     hash_size = primes[++prime_index];
  1033.  
  1034.     delete [] base;
  1035.     base = (LongLiteralValue **) memset(new LongLiteralValue *[hash_size], 0, hash_size * sizeof(LongLiteralValue *));
  1036.  
  1037.     //
  1038.     // Recall that the 0th element is unused.
  1039.     //
  1040.     for (int i = 1; i < symbol_pool.Length(); i++)
  1041.     {
  1042.         LongLiteralValue *llv = symbol_pool[i];
  1043.         int k = Hash(llv -> value) % hash_size; // the hash function for LongInt values is cheap so we don't need to save it.
  1044.         llv -> next = base[k];
  1045.         base[k] = llv;
  1046.     }
  1047.  
  1048.     return;
  1049. }
  1050.  
  1051.  
  1052. LongLiteralValue *LongLiteralTable::FindOrInsert(LongInt value)
  1053. {
  1054.     int k = Hash(value) % hash_size;
  1055.  
  1056.     LongLiteralValue *lit;
  1057.     for (lit = base[k]; lit; lit = (LongLiteralValue *) lit -> next)
  1058.     {
  1059.         if (lit -> value == value)
  1060.             return lit;
  1061.     }
  1062.  
  1063.     lit = new LongLiteralValue();
  1064.     lit -> Initialize(value, symbol_pool.Length());
  1065.     symbol_pool.Next() = lit;
  1066.  
  1067.     lit -> next = base[k];
  1068.     base[k] = lit;
  1069.  
  1070.     //
  1071.     // If the number of unique elements in the hash table exceeds 2 times
  1072.     // the size of the base, and we have not yet reached the maximum
  1073.     // allowable size for a base, reallocate a larger base and rehash
  1074.     // the elements.
  1075.     //
  1076.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1077.         Rehash();
  1078.  
  1079.     return lit;
  1080. }
  1081.  
  1082.  
  1083. int FloatLiteralTable::primes[] = {DEFAULT_HASH_SIZE, 2039, 4093, MAX_HASH_SIZE};
  1084.  
  1085. FloatLiteralTable::FloatLiteralTable(LiteralValue *bad_value_) : symbol_pool(16384),
  1086.                                                                  hash_size(primes[0]),
  1087.                                                                  prime_index(0),
  1088.                                                                  bad_value(bad_value_)
  1089. {
  1090.     base = (FloatLiteralValue **) memset(new FloatLiteralValue *[hash_size], 0, hash_size * sizeof(FloatLiteralValue *));
  1091.     symbol_pool.Next() = NULL; // do not use the 0th element
  1092. }
  1093.  
  1094. FloatLiteralTable::~FloatLiteralTable()
  1095. {
  1096. /*
  1097. int n;
  1098. int num_slots = 0;
  1099. int total = 0;
  1100. for (n = 0; n < hash_size; n++)
  1101. {
  1102. int num = 0;
  1103. for (LiteralValue *s = base[n]; s; s = s -> next)
  1104.     num++;
  1105. if (num > 0)
  1106. {
  1107. num_slots++;
  1108. total += num;
  1109. }
  1110. }
  1111.  
  1112. if (num_slots > 0)
  1113. {
  1114. Coutput << "\nDestroying the float table with " << total
  1115.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  1116. for (n = 0; n < hash_size; n++)
  1117. {
  1118. int num = 0;
  1119. for (LiteralValue *s = base[n]; s; s = s -> next)
  1120.     num++;
  1121. if (num > 0)
  1122. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  1123. }
  1124. }
  1125. if (hash_size < total)
  1126.     total = total;
  1127. */
  1128.  
  1129.     for (int i = 0; i < symbol_pool.Length(); i++)
  1130.         delete symbol_pool[i];
  1131.     delete [] base;
  1132. }
  1133.  
  1134.  
  1135. LiteralValue *FloatLiteralTable::FindOrInsertFloat(LiteralSymbol *literal)
  1136. {
  1137.     char *name = new char[literal -> NameLength() + 1];
  1138.     for (size_t i = 0; i < literal -> NameLength(); i++)
  1139.         name[i] = (char) literal -> Name()[i];
  1140.     name[literal -> NameLength()] = U_NULL;
  1141.  
  1142.     //
  1143.     // JLS 3.10.2 states it is an error for a literal to round to infinity or 0
  1144.     // Passing the second parameter tells the constructor to set value to NaN
  1145.     // if the literal is invalid.
  1146.     //
  1147.     IEEEfloat value = IEEEfloat(name, true);
  1148.  
  1149.     literal -> value = (value.IsNaN() ? bad_value : FindOrInsert(value));
  1150.  
  1151.     delete [] name;
  1152.  
  1153.     return literal -> value;
  1154. }
  1155.  
  1156.  
  1157. void FloatLiteralTable::Rehash()
  1158. {
  1159.     hash_size = primes[++prime_index];
  1160.  
  1161.     delete [] base;
  1162.     base = (FloatLiteralValue **) memset(new FloatLiteralValue *[hash_size], 0, hash_size * sizeof(FloatLiteralValue *));
  1163.  
  1164.     //
  1165.     // Recall that the 0th element is unused.
  1166.     //
  1167.     for (int i = 1; i < symbol_pool.Length(); i++)
  1168.     {
  1169.         FloatLiteralValue *flv = symbol_pool[i];
  1170.         int k = Hash(flv -> value) % hash_size; // the hash function for float values is cheap so we don't need to save it.
  1171.         flv -> next = base[k];
  1172.         base[k] = flv;
  1173.     }
  1174.  
  1175.     return;
  1176. }
  1177.  
  1178.  
  1179. FloatLiteralValue *FloatLiteralTable::FindOrInsert(IEEEfloat value)
  1180. {
  1181.     int k = Hash(value) % hash_size;
  1182.  
  1183.     FloatLiteralValue *lit;
  1184.     for (lit = base[k]; lit; lit = (FloatLiteralValue *) lit -> next)
  1185.     {
  1186.         if (lit -> value.equals(value))
  1187.             return lit;
  1188.     }
  1189.  
  1190.     lit = new FloatLiteralValue();
  1191.     lit -> Initialize(value, symbol_pool.Length());
  1192.     symbol_pool.Next() = lit;
  1193.  
  1194.     lit -> next = base[k];
  1195.     base[k] = lit;
  1196.  
  1197.     //
  1198.     // If the number of unique elements in the hash table exceeds 2 times
  1199.     // the size of the base, and we have not yet reached the maximum
  1200.     // allowable size for a base, reallocate a larger base and rehash
  1201.     // the elements.
  1202.     //
  1203.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1204.         Rehash();
  1205.  
  1206.     return lit;
  1207. }
  1208.  
  1209.  
  1210. int DoubleLiteralTable::primes[] = {DEFAULT_HASH_SIZE, 2039, 4093, MAX_HASH_SIZE};
  1211.  
  1212. DoubleLiteralTable::DoubleLiteralTable(LiteralValue *bad_value_) : symbol_pool(16384),
  1213.                                                                    hash_size(primes[0]),
  1214.                                                                    prime_index(0),
  1215.                                                                    bad_value(bad_value_)
  1216. {
  1217.     base = (DoubleLiteralValue **) memset(new DoubleLiteralValue *[hash_size], 0, hash_size * sizeof(DoubleLiteralValue *));
  1218.     symbol_pool.Next() = NULL; // do not use the 0th element
  1219. }
  1220.  
  1221. DoubleLiteralTable::~DoubleLiteralTable()
  1222. {
  1223. /*
  1224. int n;
  1225. int num_slots = 0;
  1226. int total = 0;
  1227. for (n = 0; n < hash_size; n++)
  1228. {
  1229. int num = 0;
  1230. for (LiteralValue *s = base[n]; s; s = s -> next)
  1231.     num++;
  1232. if (num > 0)
  1233. {
  1234. num_slots++;
  1235. total += num;
  1236. }
  1237. }
  1238.  
  1239. if (num_slots > 0)
  1240. {
  1241. Coutput << "\nDestroying the double table with " << total
  1242.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  1243. for (n = 0; n < hash_size; n++)
  1244. {
  1245. int num = 0;
  1246. for (LiteralValue *s = base[n]; s; s = s -> next)
  1247.     num++;
  1248. if (num > 0)
  1249. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  1250. }
  1251. }
  1252. if (hash_size < total)
  1253.     total = total;
  1254. */
  1255.     for (int i = 0; i < symbol_pool.Length(); i++)
  1256.         delete symbol_pool[i];
  1257.     delete [] base;
  1258. }
  1259.  
  1260.  
  1261. LiteralValue *DoubleLiteralTable::FindOrInsertDouble(LiteralSymbol *literal)
  1262. {
  1263.     char *name = new char[literal -> NameLength() + 1];
  1264.     for (size_t i = 0; i < literal -> NameLength(); i++)
  1265.         name[i] = (char) literal -> Name()[i];
  1266.     name[literal -> NameLength()] = U_NULL;
  1267.  
  1268.     //
  1269.     // JLS 3.10.2 states it is an error for a literal to round to infinity or 0
  1270.     // Passing the second parameter tells the constructor to set value to NaN
  1271.     // if the literal is invalid.
  1272.     //
  1273.     IEEEdouble value = IEEEdouble(name, true);
  1274.  
  1275.     literal -> value = (value.IsNaN() ? bad_value : FindOrInsert(value));
  1276.  
  1277.     delete [] name;
  1278.  
  1279.     return literal -> value;
  1280. }
  1281.  
  1282.  
  1283. void DoubleLiteralTable::Rehash()
  1284. {
  1285.     hash_size = primes[++prime_index];
  1286.  
  1287.     delete [] base;
  1288.     base = (DoubleLiteralValue **) memset(new DoubleLiteralValue *[hash_size], 0, hash_size * sizeof(DoubleLiteralValue *));
  1289.  
  1290.     //
  1291.     // Recall that the 0th element is unused.
  1292.     //
  1293.     for (int i = 1; i < symbol_pool.Length(); i++)
  1294.     {
  1295.         DoubleLiteralValue *dlv = symbol_pool[i];
  1296.         int k = Hash(dlv -> value) % hash_size; // the hash function for double values is cheap so we don't need to save it.
  1297.         dlv -> next = base[k];
  1298.         base[k] = dlv;
  1299.     }
  1300.  
  1301.     return;
  1302. }
  1303.  
  1304.  
  1305. DoubleLiteralValue *DoubleLiteralTable::FindOrInsert(IEEEdouble value)
  1306. {
  1307.     int k = Hash(value) % hash_size;
  1308.  
  1309.     DoubleLiteralValue *lit;
  1310.     for (lit = base[k]; lit; lit = (DoubleLiteralValue *) lit -> next)
  1311.     {
  1312.         if (lit -> value.equals(value))
  1313.             return lit;
  1314.     }
  1315.  
  1316.     lit = new DoubleLiteralValue();
  1317.     lit -> Initialize(value, symbol_pool.Length());
  1318.     symbol_pool.Next() = lit;
  1319.  
  1320.     lit -> next = base[k];
  1321.     base[k] = lit;
  1322.  
  1323.     //
  1324.     // If the number of unique elements in the hash table exceeds 2 times
  1325.     // the size of the base, and we have not yet reached the maximum
  1326.     // allowable size for a base, reallocate a larger base and rehash
  1327.     // the elements.
  1328.     //
  1329.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1330.         Rehash();
  1331.  
  1332.     return lit;
  1333. }
  1334.  
  1335.  
  1336. LiteralValue *Utf8LiteralTable::FindOrInsertString(LiteralSymbol *literal)
  1337. {
  1338.     wchar_t *name = literal -> Name();
  1339.  
  1340.     int literal_length = literal -> NameLength();
  1341.  
  1342.     char *value = new char[literal_length * 3]; // should be big enough for the worst case
  1343.     int len = 0,
  1344.         i;
  1345.     for (i = 1; i < literal_length && name[i] != U_DOUBLE_QUOTE; i++)  // start at 1 to skip the initial \"
  1346.     {
  1347.         int ch = name[i];
  1348.  
  1349.         if (ch == U_BACKSLASH)
  1350.         {
  1351.             if (name[i + 1] == U_b)
  1352.             {
  1353.                 i++;
  1354.                 ch = U_BACKSPACE;
  1355.             }
  1356.             else if (name[i + 1] == U_t)
  1357.             {
  1358.                 i++;
  1359.                 ch = U_HORIZONTAL_TAB;
  1360.             }
  1361.             else if (name[i + 1] == U_n)
  1362.             {
  1363.                 i++;
  1364.                 ch = U_LINE_FEED;
  1365.             }
  1366.             else if (name[i + 1] == U_f)
  1367.             {
  1368.                 i++;
  1369.                 ch = U_FORM_FEED;
  1370.             }
  1371.             else if (name[i + 1] == U_r)
  1372.             {
  1373.                 i++;
  1374.                 ch = U_CARRIAGE_RETURN;
  1375.             }
  1376.             else if (name[i + 1] == U_DOUBLE_QUOTE)
  1377.             {
  1378.                 i++;
  1379.                 ch = U_DOUBLE_QUOTE;
  1380.             }
  1381.             else if (name[i + 1] == U_SINGLE_QUOTE)
  1382.             {
  1383.                 i++;
  1384.                 ch = U_SINGLE_QUOTE;
  1385.             }
  1386.             else if (name[i + 1] == U_BACKSLASH)
  1387.             {
  1388.                 i++;
  1389.                 ch = U_BACKSLASH;
  1390.             }
  1391.             else if (Code::IsDigit(name[i + 1]))
  1392.             {
  1393.                 int digit = name[++i] - U_0;
  1394.  
  1395.                 if (digit > 7) // The first digit must be an octal digit
  1396.                     ch = -1;
  1397.                 else
  1398.                 {
  1399.                     ch = digit;
  1400.                     if (Code::IsDigit(name[i + 1]))
  1401.                     {
  1402.                         digit = name[i + 1] - U_0;
  1403.                         if (digit < 8)
  1404.                         {
  1405.                             ch = ch * 8 + digit;
  1406.                             i++;
  1407.                             if (Code::IsDigit(name[i + 1]))
  1408.                             {
  1409.                                 digit = name[i + 1] - U_0;
  1410.                                 if (ch <= 0x1F && digit < 8)
  1411.                                 {
  1412.                                     ch = ch * 8 + digit;
  1413.                                     i++;
  1414.                                 }
  1415.                             }
  1416.                         }
  1417.                     }
  1418.                 }
  1419.             }
  1420.             else ch = -1;
  1421.         }
  1422.  
  1423.         if (ch < 0)
  1424.              break;
  1425.         else if (ch == 0)
  1426.         {
  1427.              value[len++] = (char) 0xC0;
  1428.              value[len++] = (char) 0x80;
  1429.         }
  1430.         else if (ch <= 0x007F)
  1431.              value[len++] = (char) ch;
  1432.         else if (ch <= 0x07FF)
  1433.         {
  1434.              value[len++] = (char) ((char) 0xC0 | (char) ((ch >> 6) & 0x001F)); // bits 6-10
  1435.              value[len++] = (char) ((char) 0x80 | (char) (ch & 0x003F));        // bits 0-5
  1436.         }
  1437.         else
  1438.         {
  1439.              value[len++] = (char) ((char) 0xE0 | (char) ((ch >> 12) & 0x000F));
  1440.              value[len++] = (char) ((char) 0x80 | (char) ((ch >> 6) & 0x003F));
  1441.              value[len++] = (char) ((char) 0x80 | (char) (ch & 0x3F));
  1442.         }
  1443.     }
  1444.  
  1445.     value[len] = U_NULL;
  1446.     literal -> value = (i < literal_length && name[i] != U_DOUBLE_QUOTE ? bad_value : FindOrInsert(value, len));
  1447.  
  1448.     delete [] value;
  1449.     return literal -> value;
  1450. }
  1451.  
  1452.  
  1453. Utf8LiteralValue *Utf8LiteralTable::FindOrInsert(wchar_t ch)
  1454. {
  1455.     int len = 0;
  1456.     char str[4];
  1457.  
  1458.     if (ch == 0)
  1459.     {
  1460.          str[len++] = (char) 0xC0;
  1461.          str[len++] = (char) 0x80;
  1462.     }
  1463.     else if (ch <= 0x007F)
  1464.          str[len++] = (char) ch;
  1465.     else if (ch <= 0x07FF)
  1466.     {
  1467.          str[len++] = (char) ((char) 0xC0 | (char) ((ch >> 6) & 0x001F)); // bits 6-10
  1468.          str[len++] = (char) ((char) 0x80 | (char) (ch & 0x003F));        // bits 0-5
  1469.     }
  1470.     else
  1471.     {
  1472.          str[len++] = (char) ((char) 0xE0 | (char) ((ch >> 12) & 0x000F));
  1473.          str[len++] = (char) ((char) 0x80 | (char) ((ch >> 6) & 0x003F));
  1474.          str[len++] = (char) ((char) 0x80 | (char) (ch & 0x3F));
  1475.     }
  1476.  
  1477.     str[len] = U_NULL;
  1478.  
  1479.     return FindOrInsert(str, len);
  1480. }
  1481.  
  1482.  
  1483. void Utf8LiteralTable::Rehash()
  1484. {
  1485.     hash_size = primes[++prime_index];
  1486.  
  1487.     delete [] base;
  1488.     base = (Utf8LiteralValue **) memset(new Utf8LiteralValue *[hash_size], 0, hash_size * sizeof(Utf8LiteralValue *));
  1489.  
  1490.     //
  1491.     // Recall that the 0th element is unused.
  1492.     //
  1493.     for (int i = 1; i < symbol_pool.Length(); i++)
  1494.     {
  1495.         Utf8LiteralValue *ulv = symbol_pool[i];
  1496.         int k = ulv -> hash_address % hash_size;
  1497.         ulv -> next = base[k];
  1498.         base[k] = ulv;
  1499.     }
  1500.  
  1501.     return;
  1502. }
  1503.  
  1504.  
  1505. int Utf8LiteralTable::primes[] = {DEFAULT_HASH_SIZE, 8191, 16411, MAX_HASH_SIZE};
  1506.  
  1507. Utf8LiteralTable::Utf8LiteralTable(LiteralValue *bad_value_) : symbol_pool(16384),
  1508.                                                                hash_size(primes[0]),
  1509.                                                                prime_index(0),
  1510.                                                                bad_value(bad_value_)
  1511. {
  1512.     base = (Utf8LiteralValue **) memset(new Utf8LiteralValue *[hash_size], 0, hash_size * sizeof(Utf8LiteralValue *));
  1513.     symbol_pool.Next() = NULL; // do not use the 0th element
  1514. }
  1515.  
  1516.  
  1517. Utf8LiteralTable::~Utf8LiteralTable()
  1518. {
  1519. /*
  1520. int n;
  1521. int num_slots = 0;
  1522. int total = 0;
  1523. for (n = 0; n < hash_size; n++)
  1524. {
  1525. int num = 0;
  1526. for (LiteralValue *s = base[n]; s; s = s -> next)
  1527.     num++;
  1528. if (num > 0)
  1529. {
  1530. num_slots++;
  1531. total += num;
  1532. }
  1533. }
  1534.  
  1535. if (num_slots > 0)
  1536. {
  1537. Coutput << "\nDestroying the Utf8 table with " << total
  1538.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  1539. for (n = 0; n < hash_size; n++)
  1540. {
  1541. int num = 0;
  1542. for (LiteralValue *s = base[n]; s; s = s -> next)
  1543.     num++;
  1544. if (num > 0)
  1545. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  1546. }
  1547. }
  1548. if (hash_size < total)
  1549.     total = total;
  1550. */
  1551.     for (int i = 0; i < symbol_pool.Length(); i++)
  1552.         delete symbol_pool[i];
  1553.     delete [] base;
  1554. }
  1555.  
  1556.  
  1557. Utf8LiteralValue *Utf8LiteralTable::FindOrInsert(const char *str, int len)
  1558. {
  1559.     unsigned hash_address = Hash(str, len);
  1560.     int k = hash_address % hash_size;
  1561.  
  1562.     Utf8LiteralValue *lit;
  1563.     for (lit = base[k]; lit; lit = (Utf8LiteralValue *) lit -> next)
  1564.     {
  1565.         if (len == lit -> length)
  1566.         {
  1567.             if (memcmp(lit -> value, str, len * sizeof(char)) == 0)
  1568.                  return lit;
  1569.         }
  1570.     }
  1571.  
  1572.     lit = new Utf8LiteralValue();
  1573.     lit -> Initialize(str, len, hash_address, symbol_pool.Length());
  1574.     symbol_pool.Next() = lit;
  1575.  
  1576.     lit -> next = base[k];
  1577.     base[k] = lit;
  1578.  
  1579.     //
  1580.     // If the number of unique elements in the hash table exceeds 2 times
  1581.     // the size of the base, and we have not yet reached the maximum
  1582.     // allowable size for a base, reallocate a larger base and rehash
  1583.     // the elements.
  1584.     //
  1585.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1586.         Rehash();
  1587.  
  1588.     return lit;
  1589. }
  1590.  
  1591.  
  1592. void Utf8LiteralTable::EvaluateConstant(AstExpression *expression, int start, int end)
  1593. {
  1594.     if (end - start > 1)
  1595.     {
  1596.         int length = 0;
  1597.         for (int i = start; i < end; i++)
  1598.         {
  1599.             Utf8LiteralValue *literal = (*utf8_literals)[i];
  1600.             length += literal -> length;
  1601.         }
  1602.         char *str = new char[length + 1]; // +1 for '\0'
  1603.  
  1604.         int index = 0;
  1605.         for (int k = start; k < end; k++)
  1606.         {
  1607.             Utf8LiteralValue *literal = (*utf8_literals)[k];
  1608.             assert(literal -> value);
  1609.  
  1610.             memmove(&str[index], literal -> value, literal -> length * sizeof(char));
  1611.             index += literal -> length;
  1612.         }
  1613.         str[length] = U_NULL;
  1614.  
  1615.         expression -> value = FindOrInsert(str, length);
  1616.  
  1617.         delete [] str;
  1618.     }
  1619.     return;
  1620. }
  1621.  
  1622.  
  1623. bool Utf8LiteralTable::IsConstant(AstExpression *expression,
  1624.     Symbol *string_symbol)
  1625. {
  1626.     if (expression -> symbol == string_symbol && expression -> IsConstant())
  1627.     {
  1628.         // The EvaluateConstant method only works with
  1629.         // Utf8LiteralValue* types. Checking that
  1630.         // the expression is of type String is
  1631.         // enough to determine the type, but we do
  1632.         // an extra RTTI/cast check to make sure.
  1633.  
  1634.         assert(expression -> value);
  1635.  
  1636.         Utf8LiteralValue *literal =
  1637. #ifndef HAVE_DYNAMIC_CAST
  1638.         (Utf8LiteralValue *) expression -> value;
  1639. #else
  1640.             dynamic_cast<Utf8LiteralValue *>(expression -> value);
  1641.             if (! literal) {
  1642. #ifdef HAVE_RTTI
  1643.                 const type_info& t = typeid(*(expression -> value));
  1644.                 const char *name = t.name();
  1645.                 fprintf(stderr, "expr value not a Utf8LiteralValue %s%s\n",
  1646.                     "it's type was ", name);
  1647. #endif
  1648.                 assert(literal && "expr value not a Utf8LiteralValue");
  1649.             }
  1650. #endif
  1651.         assert(literal -> value);
  1652.  
  1653.         utf8_literals -> Next() = literal;
  1654.         return true;
  1655.     }
  1656.  
  1657.     AstBinaryExpression *binary_expression;
  1658.     AstCastExpression *cast_expression;
  1659.     AstParenthesizedExpression *parenthesized_expression;
  1660.     if ((binary_expression = expression -> BinaryExpressionCast()))
  1661.     {
  1662.         int left_start_marker = utf8_literals -> Length();
  1663.  
  1664.         AstExpression *left  = binary_expression -> left_expression,
  1665.                       *right = binary_expression -> right_expression;
  1666.  
  1667.         bool left_is_constant = IsConstant(left, string_symbol);
  1668.  
  1669.         int left_end_marker = utf8_literals -> Length();
  1670.  
  1671.         bool right_is_constant = IsConstant(right, string_symbol);
  1672.         if (left_is_constant && right_is_constant)
  1673.              return true;
  1674.  
  1675.         if (left_is_constant)
  1676.              EvaluateConstant(left, left_start_marker, left_end_marker);
  1677.         else if (right_is_constant)
  1678.              EvaluateConstant(right, left_end_marker,
  1679.                  utf8_literals -> Length());
  1680.  
  1681.         utf8_literals -> Reset(left_start_marker);
  1682.     }
  1683.     else if ((cast_expression = expression -> CastExpressionCast()))
  1684.          return IsConstant(cast_expression -> expression, string_symbol);
  1685.     else if ((parenthesized_expression = expression -> ParenthesizedExpressionCast()))
  1686.          return IsConstant(parenthesized_expression -> expression,
  1687.              string_symbol);
  1688.  
  1689.     return false; // Not a constant String expression
  1690. }
  1691.  
  1692.  
  1693.  
  1694. void Utf8LiteralTable::CheckStringConstant(AstExpression *expression)
  1695. {
  1696.     // This tuple object is used in the IsConstant() method,
  1697.     // it flattens the expresion tree into a set of utf8 literals.
  1698.     utf8_literals = new Tuple<Utf8LiteralValue *>(256);
  1699.  
  1700.     // CheckStringConstant must be called with an expression
  1701.     // argument that has the symbol for the String type.
  1702.     Symbol *string_symbol = expression -> symbol;
  1703.  
  1704.     if (IsConstant(expression, string_symbol))
  1705.         EvaluateConstant(expression, 0, utf8_literals -> Length());
  1706.  
  1707.     delete utf8_literals;
  1708.  
  1709.     return;
  1710. }
  1711.  
  1712.  
  1713. int LiteralLookupTable::primes[] = {DEFAULT_HASH_SIZE, 2039, 4093, MAX_HASH_SIZE};
  1714.  
  1715. LiteralLookupTable::LiteralLookupTable() : symbol_pool(16384),
  1716.                                            hash_size(primes[0]),
  1717.                                            prime_index(0)
  1718. {
  1719.     base = (LiteralSymbol **) memset(new LiteralSymbol *[hash_size], 0, hash_size * sizeof(LiteralSymbol *));
  1720. }
  1721.  
  1722. LiteralLookupTable::~LiteralLookupTable()
  1723. {
  1724. /*
  1725. int n;
  1726. int num_slots = 0;
  1727. int total = 0;
  1728. for (n = 0; n < hash_size; n++)
  1729. {
  1730. int num = 0;
  1731. for (Symbol *s = base[n]; s; s = s -> next)
  1732.     num++;
  1733. if (num > 0)
  1734. {
  1735. num_slots++;
  1736. total += num;
  1737. }
  1738. }
  1739.  
  1740. if (num_slots > 0)
  1741. {
  1742. Coutput << "\nDestroying the Literal table with " << total
  1743.         << " elements and base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  1744. for (n = 0; n < hash_size; n++)
  1745. {
  1746. int num = 0;
  1747. for (Symbol *s = base[n]; s; s = s -> next)
  1748.     num++;
  1749. if (num > 0)
  1750. Coutput << "    slot " << n << " contains " << num << " element(s)\n";
  1751. }
  1752. }
  1753. if (hash_size < total)
  1754.     total = total;
  1755. */
  1756.     for (int i = 0; i < symbol_pool.Length(); i++)
  1757.         delete symbol_pool[i];
  1758.     delete [] base;
  1759. }
  1760.  
  1761.  
  1762. void LiteralLookupTable::Rehash()
  1763. {
  1764.     hash_size = primes[++prime_index];
  1765.  
  1766.     delete [] base;
  1767.     base = (LiteralSymbol **) memset(new LiteralSymbol *[hash_size], 0, hash_size * sizeof(LiteralSymbol *));
  1768.  
  1769.     for (int i = 0; i < symbol_pool.Length(); i++)
  1770.     {
  1771.         LiteralSymbol *ls = symbol_pool[i];
  1772.         int k = ls -> hash_address % hash_size;
  1773.         ls -> next = base[k];
  1774.         base[k] = ls;
  1775.     }
  1776.  
  1777.     return;
  1778. }
  1779.  
  1780.  
  1781. LiteralSymbol *LiteralLookupTable::FindOrInsertLiteral(wchar_t *str, size_t len)
  1782. {
  1783.     unsigned hash_address = Hash(str, len);
  1784.     int k = hash_address % hash_size;
  1785.     LiteralSymbol *symbol;
  1786.     for (symbol = base[k]; symbol; symbol = (LiteralSymbol *) symbol -> next)
  1787.     {
  1788.         if (len == symbol -> NameLength() && memcmp(symbol -> Name(), str, len * sizeof(wchar_t)) == 0)
  1789.             return symbol;
  1790.     }
  1791.  
  1792.     symbol = new LiteralSymbol();
  1793.     symbol_pool.Next() = symbol;
  1794.     symbol -> Initialize(str, hash_address, len);
  1795.  
  1796.     symbol -> next = base[k];
  1797.     base[k] = symbol;
  1798.  
  1799.     //
  1800.     // If the number of unique elements in the hash table exceeds 2 times
  1801.     // the size of the base, and we have not yet reached the maximum
  1802.     // allowable size for a base, reallocate a larger base and rehash
  1803.     // the elements.
  1804.     //
  1805.     if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  1806.         Rehash();
  1807.  
  1808.     return symbol;
  1809. }
  1810.  
  1811. #ifdef    HAVE_JIKES_NAMESPACE
  1812. }            // Close namespace Jikes block
  1813. #endif
  1814.  
  1815.