my @attrs = ();
my @values = ();
my @hashes = ();
+my @table = ();
+my @links = ();
+
+my $hasSetter = "false";
my $inside = 0;
my $name;
@attrs = ();
@values = ();
@hashes = ();
+ @table = ();
+ @links = ();
$inside = 0;
} elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) {
if ($att =~ m/Function/) {
push(@values, { "type" => "Function", "function" => $val, "params" => (length($param) ? $param : "") });
#printf STDERR "WARNING: Number of arguments missing for $key/$val\n" if (length($param) == 0);
+ } elsif ($att =~ m/Accessor/) {
+ my $get = $val;
+ my $put = "nullptr";
+ $hasSetter = "true";
+ push(@values, { "type" => "Accessor", "get" => $get, "put" => $put });
} elsif (length($att)) {
my $get = $val;
- my $put = !($att =~ m/ReadOnly/) ? "set" . jsc_ucfirst($val) : "0";
+ my $put = "0";
+ if (!($att =~ m/ReadOnly/)) {
+ $put = "set" . jsc_ucfirst($val);
+ }
+ $hasSetter = "true";
push(@values, { "type" => "Property", "get" => $get, "put" => $put });
} else {
push(@values, { "type" => "Lexer", "value" => $val });
sub calcCompactHashSize()
{
- my @table = ();
- my @links = ();
my $compactHashSize = ceilingToPowerOf2(2 * @keys);
$compactHashSizeMask = $compactHashSize - 1;
$compactSize = $compactHashSize;
# Paul Hsieh's SuperFastHash
# http://www.azillionmonkeys.com/qed/hash.html
-# Ported from UString..
sub hashValue($) {
my @chars = split(/ */, $_[0]);
}
# Handle end case
- if ($rem !=0) {
+ if ($rem != 0) {
$hash += ord($chars[$s]);
$hash ^= (leftShift($hash, 11)% $EXP2_32);
$hash += $hash >> 17;
$hash += ($hash >> 15);
$hash = $hash% $EXP2_32;
$hash ^= (leftShift($hash, 10)% $EXP2_32);
-
- # this avoids ever returning a hash code of 0, since that is used to
- # signal "hash not computed yet", using a value that is likely to be
- # effectively the same as 0 when the low bits are masked
- $hash = 0x80000000 if ($hash == 0);
+
+ # Save 8 bits for StringImpl to use as flags.
+ $hash &= 0xffffff;
+
+ # This avoids ever returning a hash code of 0, since that is used to
+ # signal "hash not computed yet". Setting the high bit maintains
+ # reasonable fidelity to a hash code of 0 because it is likely to yield
+ # exactly 0 when hash lookup masks out the high bits.
+ $hash = (0x80000000 >> 8) if ($hash == 0);
return $hash;
}
my $nameEntries = "${name}Values";
$nameEntries =~ s/:/_/g;
+ my $nameIndex = "${name}Index";
+ $nameIndex =~ s/:/_/g;
+ print "\n#include \"JSCBuiltins.h\"\n";
print "\n#include \"Lookup.h\"\n" if ($includelookup);
+
if ($useNameSpace) {
print "\nnamespace ${useNameSpace} {\n";
print "\nusing namespace JSC;\n";
} else {
print "\nnamespace JSC {\n";
}
- my $count = scalar @keys + 1;
- print "\nstatic const struct HashTableValue ${nameEntries}\[$count\] = {\n";
+
+ print "\nstatic const struct CompactHashIndex ${nameIndex}\[$compactSize\] = {\n";
+ for (my $i = 0; $i < $compactSize; $i++) {
+ my $T = -1;
+ if (defined($table[$i])) { $T = $table[$i]; }
+ my $L = -1;
+ if (defined($links[$i])) { $L = $links[$i]; }
+ print " { $T, $L },\n";
+ }
+ print "};\n\n";
+
+ my $packedSize = scalar @keys;
+ print "\nstatic const struct HashTableValue ${nameEntries}\[$packedSize\] = {\n";
my $i = 0;
foreach my $key (@keys) {
my $firstValue = "";
my $secondValue = "";
+ my $firstCastStr = "";
+ my $secondCastStr = "";
if ($values[$i]{"type"} eq "Function") {
+ $firstCastStr = "static_cast<NativeFunction>";
$firstValue = $values[$i]{"function"};
$secondValue = $values[$i]{"params"};
+ } elsif ($values[$i]{"type"} eq "Accessor") {
+ $firstCastStr = "static_cast<NativeFunction>";
+ $secondCastStr = "static_cast<NativeFunction>";
+ $firstValue = $values[$i]{"get"};
+ $secondValue = $values[$i]{"put"};
} elsif ($values[$i]{"type"} eq "Property") {
+ $firstCastStr = "static_cast<PropertySlot::GetValueFunc>";
+ $secondCastStr = "static_cast<PutPropertySlot::PutValueFunc>";
$firstValue = $values[$i]{"get"};
$secondValue = $values[$i]{"put"};
} elsif ($values[$i]{"type"} eq "Lexer") {
$firstValue = $values[$i]{"value"};
$secondValue = "0";
}
- print " { \"$key\", $attrs[$i], (intptr_t)$firstValue, (intptr_t)$secondValue },\n";
+
+ my $intrinsic = "NoIntrinsic";
+ $intrinsic = "FromCharCodeIntrinsic" if ($key eq "fromCharCode");
+ if ($name eq "arrayPrototypeTable") {
+ $intrinsic = "ArrayPushIntrinsic" if ($key eq "push");
+ $intrinsic = "ArrayPopIntrinsic" if ($key eq "pop");
+ }
+ if ($name eq "regExpPrototypeTable") {
+ $intrinsic = "RegExpExecIntrinsic" if ($key eq "exec");
+ $intrinsic = "RegExpTestIntrinsic" if ($key eq "test");
+ }
+
+ if ($values[$i]{"type"} eq "Function") {
+ my $tableHead = $name;
+ $tableHead =~ s/Table$//;
+ print " #if JSC_BUILTIN_EXISTS(" . uc($tableHead . $key) .")\n";
+ print " { \"$key\", (($attrs[$i]) & ~Function) | Builtin, $intrinsic, (intptr_t)static_cast<BuiltinGenerator>(" . $tableHead . ucfirst($key) . "CodeGenerator), (intptr_t)$secondValue },\n";
+ print " #else\n"
+ }
+ print " { \"$key\", $attrs[$i], $intrinsic, (intptr_t)" . $firstCastStr . "($firstValue), (intptr_t)" . $secondCastStr . "($secondValue) },\n";
+ if ($values[$i]{"type"} eq "Function") {
+ print " #endif\n"
+ }
$i++;
}
- print " { 0, 0, 0, 0 }\n";
print "};\n\n";
- print "extern JSC_CONST_HASHTABLE HashTable $name =\n";
- print " \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n";
+ print "JS_EXPORT_PRIVATE extern const struct HashTable $name =\n";
+ print " \{ $packedSize, $compactHashSizeMask, $hasSetter, $nameEntries, 0, $nameIndex \};\n";
print "} // namespace\n";
}