]>
git.saurik.com Git - apple/javascriptcore.git/blob - kjs/create_hash_table
   3 # Static Hashtable Generator 
   5 # (c) 2000-2002 by Harri Porten <porten@kde.org> and 
   6 #                  David Faure <faure@kde.org> 
   7 # Modified (c) 2004 by Nikolas Zimmermann <wildfox@kde.org> 
   8 # Copyright (C) 2007 Apple Inc. All rights reserved. 
  10 # Part of the KJS library. 
  12 # This library is free software; you can redistribute it and/or 
  13 # modify it under the terms of the GNU Lesser General Public 
  14 # License as published by the Free Software Foundation; either 
  15 # version 2 of the License, or (at your option) any later version. 
  17 # This library is distributed in the hope that it will be useful, 
  18 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  20 # Lesser General Public License for more details. 
  22 # You should have received a copy of the GNU Lesser General Public 
  23 # License along with this library; if not, write to the Free Software 
  24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA 
  31 my $includelookup = 0; 
  33 # Use -i as second argument to make it include "lookup.h" 
  34 $includelookup = 1 if (defined($ARGV[0]) && $ARGV[0] eq "-i"); 
  36 # Use -n as second argument to make it use the third argument as namespace parameter ie. -n KDOM 
  37 my $useNameSpace = $ARGV[1] if (defined($ARGV[0]) && $ARGV[0] eq "-n"); 
  39 print STDERR 
"Creating hashtable for $file\n"; 
  40 open(IN
, $file) or die "No such file $file"; 
  64     } elsif (/^\@begin/ && !$inside) { 
  65       if (/^\@begin\s*([:_\w]+)\s*\d*\s*$/) { 
  69          printf STDERR 
"WARNING: \@begin without table name and hashsize, skipping $_\n"; 
  71     } elsif (/^\@end\s*$/ && $inside) { 
  84     } elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) { 
  91       push(@hashes, hashValue
($key)); 
  92       printf STDERR 
"WARNING: Number of arguments missing for $key/$val\n" 
  93         if ( $att =~ m/Function/ && length($param) == 0); 
  94       push(@attrs, length($att) > 0 ? $att : "0"); 
  95       push(@params, length($param) > 0 ? $param : "0"); 
  97       die "invalid data {" . $_ . "}"; 
 101 die "missing closing \@end" if ($inside); 
 103 sub ceilingToPowerOf2
 
 108     while ($size > $powerOf2) { 
 116   my $hashsize = ceilingToPowerOf2
(2 * @keys); 
 117   $hashSizeMask = $hashsize - 1; 
 122   foreach my $key (@keys) { 
 124     my $h = hashValue
($key) % $hashsize; 
 125     while (defined($table[$h])) { 
 126       if (defined($links[$h])) { 
 138     $maxdepth = $depth if ( $depth > $maxdepth); 
 141   # Ensure table is big enough (in case of undef entries at the end) 
 142   if ( $#table+1 < $size ) { 
 148     my ($value, $distance) = @_; 
 149     return (($value << $distance) & 0xFFFFFFFF); 
 152 # Paul Hsieh's SuperFastHash 
 153 # http://www.azillionmonkeys.com/qed/hash.html 
 154 # Ported from UString.. 
 156   my @chars = split(/ */, $_[0]); 
 158   # This hash is designed to work on 16-bit chunks at a time. But since the normal case 
 159   # (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they 
 160   # were 16-bit chunks, which should give matching results 
 162   my $EXP2_32 = 4294967296; 
 164   my $hash = 0x9e3779b9; 
 165   my $l    = scalar @chars; #I wish this was in Ruby --- Maks 
 172   for (; $l > 0; $l--) { 
 173     $hash   += ord($chars[$s]); 
 174     my $tmp = leftShift
(ord($chars[$s+1]), 11) ^ $hash; 
 175     $hash   = (leftShift
($hash, 16)% $EXP2_32) ^ $tmp; 
 177     $hash += $hash >> 11; 
 183     $hash += ord($chars[$s]); 
 184     $hash ^= (leftShift
($hash, 11)% $EXP2_32); 
 185     $hash += $hash >> 17; 
 188   # Force "avalanching" of final 127 bits 
 189   $hash ^= leftShift
($hash, 3); 
 190   $hash += ($hash >> 5); 
 191   $hash = ($hash% $EXP2_32); 
 192   $hash ^= (leftShift
($hash, 2)% $EXP2_32); 
 193   $hash += ($hash >> 15); 
 194   $hash = $hash% $EXP2_32; 
 195   $hash ^= (leftShift
($hash, 10)% $EXP2_32); 
 197   # this avoids ever returning a hash code of 0, since that is used to 
 198   # signal "hash not computed yet", using a value that is likely to be 
 199   # effectively the same as 0 when the low bits are masked 
 200   $hash = 0x80000000  if ($hash == 0); 
 208     print "/* Automatically generated from $file using $0. DO NOT EDIT ! */\n"; 
 211   my $nameEntries = "${name}Entries"; 
 212   $nameEntries =~ s/:/_/g; 
 214   print "\n#include \"lookup.h\"\n" if ($includelookup); 
 216     print "\nnamespace ${useNameSpace}\n{\n"; 
 217     print "\nusing namespace KJS;"; 
 219     print "\nnamespace KJS {\n"; 
 221   print "\nstatic const struct HashEntry ".$nameEntries."[] = {\n"; 
 224     foreach my $entry (@table) { 
 225       if (defined($entry)) { 
 226         my $key = $keys[$entry]; 
 227         print "   \{ \"" . $key . "\""; 
 228         print ", { (intptr_t)" . $values[$entry] . " }"; 
 229         print ", " . $attrs[$entry]; 
 230         print ", " . $params[$entry]; 
 232         if (defined($links[$i])) { 
 233           print "&" . $nameEntries . "[" . $links[$i] . "]" . " \}"; 
 237         print "/* " . $hashes[$entry] . " */ "; 
 239         print "   { 0, { 0 }, 0, 0, 0 }"; 
 241       print "," unless ($i == $size - 1); 
 247   print "const struct HashTable $name = "; 
 248   print "\{ 3, $size, $nameEntries, $hashSizeMask \};\n\n"; 
 249   print "} // namespace\n";