Changeset 31147 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Mar 18, 2008, 9:23:21 PM (17 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

2008-03-18 Darin Adler <Darin Adler>

Reviewed by Maciej.

  • Speed up JavaScript built-in properties by changing the hash table to take advantage of the identifier objects

5% speedup for Acid3 test 26

  • JavaScriptCore.exp: Updated.
  • kjs/create_hash_table: Compute size of hash table large enough so that there are no collisions, but don't generate the hash table.
  • kjs/identifier.h: Made the add function that returns a PassRefPtr public.
  • kjs/lexer.cpp: (KJS::Lexer::lex): Updated for change to HashTable interface.
  • kjs/lookup.cpp: (KJS::HashTable::changeKeysToIdentifiers): Added. Finds the identifier for each property so the equality comparision can be done with pointer comparision.
  • kjs/lookup.h: Made the key be a union of char* with UString::Rep* so it can hold identifiers. Added a keysAreIdentifiers flag to the HashTable. Changed the Lookup functions to be member functions of HashTable instead.
  • kjs/object.cpp: (KJS::JSObject::deleteProperty): Update for change to HashTable. (KJS::JSObject::findPropertyHashEntry): Ditto. (KJS::JSObject::getPropertyAttributes): Ditto. (KJS::JSObject::getPropertyNames): Ditto.

WebCore:

2008-03-18 Darin Adler <Darin Adler>

Reviewed by Maciej.

  • Speed up JavaScript built-in properties by changing the hash table to take advantage of the identifier objects

5% speedup for Acid3 test 26

  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::getOwnPropertySlot): Update for change to HashTable. (WebCore::JSDOMWindowBase::put): Ditto.
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::customGetOwnPropertySlot): Ditto.
  • bindings/js/JSHTMLInputElementBase.cpp: (WebCore::JSHTMLInputElementBase::getOwnPropertySlot): Ditto.
  • bindings/js/JSHistoryCustom.cpp: (WebCore::JSHistory::customGetOwnPropertySlot): Ditto.
  • bindings/js/JSLocation.cpp: (WebCore::JSLocation::customGetOwnPropertySlot): Ditto. (WebCore::JSLocation::put): Ditto.
  • bindings/js/kjs_binding.cpp: (WebCore::nonCachingStaticFunctionGetter): Ditto.
  • bindings/scripts/CodeGeneratorJS.pm: Same changes as in the create_hash_table script.
Location:
trunk/JavaScriptCore/kjs
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/create_hash_table

    r27608 r31147  
    4545my @params = ();
    4646my @hashes = ();
    47 my @table = ();
    48 my @links = ();
    4947
    5048my $inside = 0;
    5149my $name;
    5250my $size;
    53 my $hashSizeMask;
    5451my $banner = 0;
    55 sub calcTable();
     52sub calcSize();
    5653sub output();
    5754sub hashValue($);
    5855
    5956while (<IN>) {
    60   chop;
    61   s/^\s*//g;
    62   if (/^\#|^$/) {
    63       # comment. do nothing
    64     } elsif (/^\@begin/ && !$inside) {
    65       if (/^\@begin\s*([:_\w]+)\s*\d*\s*$/) {
    66         $inside = 1;
    67         $name = $1;
    68       } else {
    69          printf STDERR "WARNING: \@begin without table name and hashsize, skipping $_\n";
    70       }
     57    chomp;
     58    s/^\s+//;
     59    next if /^\#|^$/; # Comment or blank line. Do nothing.
     60    if (/^\@begin/ && !$inside) {
     61        if (/^\@begin\s*([:_\w]+)\s*\d*\s*$/) {
     62            $inside = 1;
     63            $name = $1;
     64        } else {
     65            print STDERR "WARNING: \@begin without table name, skipping $_\n";
     66        }
    7167    } elsif (/^\@end\s*$/ && $inside) {
    72 
    73       calcTable();
    74 
    75       output();
    76       @keys = ();
    77       @values = ();
    78       @attrs = ();
    79       @params = ();
    80       @table = ();
    81       @links = ();
    82       @hashes = ();
    83       $inside = 0;
     68        calcSize();
     69        output();
     70
     71        @keys = ();
     72        @values = ();
     73        @attrs = ();
     74        @params = ();
     75        @hashes = ();
     76
     77        $inside = 0;
    8478    } elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) {
    85       my $key = $1;
    86       my $val = $2;
    87       my $att = $3;
    88       my $param = $4;
    89       push(@keys, $key);
    90       push(@values, $val);
    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");
     79        my $key = $1;
     80        my $val = $2;
     81        my $att = $3;
     82        my $param = $4;
     83        push(@keys, $key);
     84        push(@values, $val);
     85        push(@hashes, hashValue($key));
     86        printf STDERR "WARNING: Number of arguments missing for $key/$val\n" if ($att =~ m/Function/ && length($param) == 0);
     87        push(@attrs, length($att) > 0 ? $att : "0");
     88        push(@params, length($param) > 0 ? $param : "0");
    9689    } elsif ($inside) {
    97       die "invalid data {" . $_ . "}";
     90        die "invalid data {" . $_ . "}";
    9891    }
    9992}
     
    113106}
    114107
    115 sub calcTable() {
    116   my $hashsize = ceilingToPowerOf2(2 * @keys);
    117   $hashSizeMask = $hashsize - 1;
    118   $size = $hashsize;
    119   my $collisions = 0;
    120   my $maxdepth = 0;
    121   my $i = 0;
    122   foreach my $key (@keys) {
    123     my $depth = 0;
    124     my $h = hashValue($key) % $hashsize;
    125     while (defined($table[$h])) {
    126       if (defined($links[$h])) {
    127         $h = $links[$h];
    128         $depth++;
    129       } else {
    130         $collisions++;
    131         $links[$h] = $size;
    132         $h = $size;
    133         $size++;
    134       }
    135     }
    136     $table[$h] = $i;
    137     $i++;
    138     $maxdepth = $depth if ( $depth > $maxdepth);
    139   }
    140 
    141   # Ensure table is big enough (in case of undef entries at the end)
    142   if ( $#table+1 < $size ) {
    143     $#table = $size-1;
    144   }
     108sub calcSize()
     109{
     110tableSizeLoop:
     111    for ($size = ceilingToPowerOf2(scalar @keys); ; $size += $size) {
     112        my @table = ();
     113        foreach my $key (@keys) {
     114            my $h = hashValue($key) % $size;
     115            next tableSizeLoop if $table[$h];
     116            $table[$h] = 1;
     117        }
     118        last;
     119    }
    145120}
    146121
     
    204179
    205180sub output() {
    206   if (!$banner) {
    207     $banner = 1;
    208     print "/* Automatically generated from $file using $0. DO NOT EDIT ! */\n";
    209   }
    210 
    211   my $nameEntries = "${name}Entries";
    212   $nameEntries =~ s/:/_/g;
    213 
    214   print "\n#include \"lookup.h\"\n" if ($includelookup);
    215   if ($useNameSpace) {
    216     print "\nnamespace ${useNameSpace}\n{\n";
    217     print "\nusing namespace KJS;";
    218   } else {
    219     print "\nnamespace KJS {\n";
    220   }
    221   print "\nstatic const struct HashEntry ".$nameEntries."[] = {\n";
    222   my $i = 0;
    223  
    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];
    231         print ", ";
    232         if (defined($links[$i])) {
    233           print "&" . $nameEntries . "[" . $links[$i] . "]" . " \}";
    234         } else {
    235           print "0 \}"
    236         }
    237         print "/* " . $hashes[$entry] . " */ ";
    238       } else {
    239         print "   { 0, { 0 }, 0, 0, 0 }";
    240       }   
    241       print "," unless ($i == $size - 1);
    242       print "\n";
    243       $i++;
    244     }
    245 
    246   print "};\n\n";
    247   print "const struct HashTable $name = ";
    248   print "\{ 3, $size, $nameEntries, $hashSizeMask \};\n\n";
    249   print "} // namespace\n";
    250 }
     181    if (!$banner) {
     182        $banner = 1;
     183        print "// Automatically generated from $file using $0. DO NOT EDIT!\n";
     184    }
     185
     186    my $nameEntries = "${name}Values";
     187    $nameEntries =~ s/:/_/g;
     188
     189    print "\n#include \"lookup.h\"\n" if ($includelookup);
     190    if ($useNameSpace) {
     191        print "\nnamespace ${useNameSpace}\n{\n";
     192        print "\nusing namespace KJS;";
     193    } else {
     194        print "\nnamespace KJS {\n";
     195    }
     196    my $count = scalar @keys + 1;
     197    print "\nstatic const struct HashTableValue ${nameEntries}[$count] = {\n";
     198    my $i = 0;
     199    foreach my $key (@keys) {
     200        print "   { \"$key\", (intptr_t)$values[$i], $attrs[$i], $params[$i] },\n";
     201        $i++;
     202    }
     203    print "   { 0, 0, 0, 0 }\n";
     204    print "};\n\n";
     205    print "const struct HashTable $name = ";
     206    print "\{ ", $size - 1, ", $nameEntries, 0 \};\n\n";
     207    print "} // namespace\n";
     208}
  • trunk/JavaScriptCore/kjs/identifier.h

    r27206 r31147  
    6262        friend bool operator==(const Identifier&, const char*);
    6363   
    64         static void remove(UString::Rep* );
     64        static void remove(UString::Rep*);
    6565
    6666        static bool equal(const UString::Rep*, const char*);
    6767        static bool equal(const UString::Rep*, const UChar*, int length);
    6868        static bool equal(const UString::Rep*, const UString::Rep*);
     69
     70        static PassRefPtr<UString::Rep> add(const char*);
    6971
    7072    private:
     
    7678            { return equal(a._ustring.rep(), b); }
    7779       
    78         static PassRefPtr<UString::Rep> add(const char*);
    7980        static PassRefPtr<UString::Rep> add(const UChar*, int length);
    8081        static PassRefPtr<UString::Rep> add(UString::Rep* r)
  • trunk/JavaScriptCore/kjs/lexer.cpp

    r30942 r31147  
    524524#endif
    525525
    526   if (state != Identifier && eatNextIdentifier)
     526  if (state != Identifier)
    527527    eatNextIdentifier = false;
    528528
     
    537537    break;
    538538  case Other:
    539     if(token == '}' || token == ';') {
     539    if (token == '}' || token == ';')
    540540      delimited = true;
     541    break;
     542  case Identifier:
     543    // Apply anonymous-function hack below (eat the identifier).
     544    if (eatNextIdentifier) {
     545      eatNextIdentifier = false;
     546      token = lex();
     547      break;
    541548    }
     549    kjsyylval.ident = makeIdentifier(m_buffer16);
     550    token = IDENT;
    542551    break;
    543552  case IdentifierOrKeyword:
    544     if ((token = Lookup::find(&mainTable, m_buffer16.data(), m_buffer16.size())) < 0) {
    545   case Identifier:
    546       // Lookup for keyword failed, means this is an identifier
    547       // Apply anonymous-function hack below (eat the identifier)
    548       if (eatNextIdentifier) {
    549         eatNextIdentifier = false;
    550         token = lex();
    551         break;
    552       }
    553       kjsyylval.ident = makeIdentifier(m_buffer16);
     553    kjsyylval.ident = makeIdentifier(m_buffer16);
     554    if ((token = mainTable.value(*kjsyylval.ident)) < 0) {
     555      // Lookup for keyword failed, means this is an identifier.
    554556      token = IDENT;
    555557      break;
    556558    }
    557 
    558     eatNextIdentifier = false;
    559     // Hack for "f = function somename() { ... }", too hard to get into the grammar
    560     if (token == FUNCTION && lastToken == '=' )
    561       eatNextIdentifier = true;
    562 
    563     if (token == CONTINUE || token == BREAK ||
    564         token == RETURN || token == THROW)
     559    // Hack for "f = function somename() { ... }"; too hard to get into the grammar.
     560    eatNextIdentifier = token == FUNCTION && lastToken == '=';
     561    if (token == CONTINUE || token == BREAK || token == RETURN || token == THROW)
    565562      restrKeyword = true;
    566563    break;
  • trunk/JavaScriptCore/kjs/lookup.cpp

    r30942 r31147  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    3  *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    4  *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
     2 *  Copyright (C) 2008 Apple Inc. All rights reserved.
    53 *
    64 *  This library is free software; you can redistribute it and/or
     
    2321#include "lookup.h"
    2422
    25 #include <wtf/Assertions.h>
    26 
    2723namespace KJS {
    2824
    29 static inline bool keysMatch(const UChar* c, unsigned len, const char* s)
     25void HashTable::createTable() const
    3026{
    31   // FIXME: This can run off the end of |s| if |c| has a U+0000 character in it.
    32   const char* end = s + len;
    33   for (; s != end; c++, s++)
    34     if (*c != *s)
    35       return false;
    36   return *s == 0;
    37 }
    38 
    39 static inline const HashEntry* findEntry(const struct HashTable* table, unsigned int hash,
    40                                          const UChar* c, unsigned int len)
    41 {
    42   ASSERT(table->type == 3);
    43    
    44   const HashEntry* e = &table->entries[hash & table->hashSizeMask];
    45 
    46   if (!e->s)
    47     return 0;
    48 
    49   do {
    50     // compare strings
    51     if (keysMatch(c, len, e->s))
    52       return e;
    53 
    54     // try next bucket
    55     e = e->next;
    56   } while (e);
    57   return 0;
    58 }
    59 
    60 const HashEntry* Lookup::findEntry(const struct HashTable* table, const Identifier& s)
    61 {
    62   return KJS::findEntry(table, s.ustring().rep()->computedHash(), s.data(), s.size());
    63 }
    64 
    65 int Lookup::find(const struct HashTable *table, const UChar *c, unsigned int len)
    66 {
    67   const HashEntry *entry = KJS::findEntry(table, UString::Rep::computeHash(c, len), c, len);
    68   if (entry)
    69     return entry->value.intValue;
    70   return -1;
    71 }
    72 
    73 int Lookup::find(const struct HashTable* table, const Identifier& s)
    74 {
    75   const HashEntry* entry = KJS::findEntry(table, s.ustring().rep()->computedHash(), s.data(), s.size());
    76   if (entry)
    77     return entry->value.intValue;
    78   return -1;
     27    ASSERT(!table);
     28    HashEntry* entries = new HashEntry[hashSizeMask + 1];
     29    for (int i = 0; i <= hashSizeMask; ++i)
     30        entries[i].key = 0;
     31    for (int i = 0; values[i].key; ++i) {
     32        UString::Rep* identifier = Identifier::add(values[i].key).releaseRef();
     33        int hashIndex = identifier->computedHash() & hashSizeMask;
     34        ASSERT(!entries[hashIndex].key);
     35        entries[hashIndex].key = identifier;
     36        entries[hashIndex].integerValue = values[i].value;
     37        entries[hashIndex].attributes = values[i].attributes;
     38        entries[hashIndex].length = values[i].length;
     39    }
     40    table = entries;
    7941}
    8042
  • trunk/JavaScriptCore/kjs/lookup.h

    r30534 r31147  
    22/*
    33 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    4  *  Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    3333namespace KJS {
    3434
    35   /**
    36    * An entry in a hash table.
    37    */
    38   struct HashEntry {
    39     /**
    40      * s is the key (e.g. a property name)
    41      */
    42     const char* s;
    43 
    44     /**
    45      * value is the result value (enum value for properties and a function pointer to a constructor factory for functions)
    46      */
    47     union {
    48       intptr_t intValue;
    49       PrototypeFunction::JSMemberFunction functionValue;
    50     } value;
    51 
    52     /**
    53      * attr is a set for flags (e.g. the property flags, see object.h)
    54      */
    55     unsigned char attr;
    56     /**
    57      * params is another number. For property hashtables, it is used to
    58      * denote the number of argument of the function
    59      */
    60     short int params;
    61     /**
    62      * next is the pointer to the next entry for the same hash value
    63      */
    64     const HashEntry* next;
    65   };
    66 
    67   /**
    68    * A hash table
    69    * Usually the hashtable is generated by the create_hash_table script, from a .table file.
    70    *
    71    * The implementation uses an array of entries, "size" is the total size of that array.
    72    * The entries between 0 and hashSize-1 are the entry points
    73    * for each hash value, and the entries between hashSize and size-1
    74    * are the overflow entries for the hash values that need one.
    75    * The "next" pointer of the entry links entry points to overflow entries,
    76    * and links overflow entries between them.
    77    */
    78   struct HashTable {
    79     /**
    80      * type is a version number. Currently always 2
    81      */
    82     int type;
    83     /**
    84      * size is the total number of entries in the hashtable, including the null entries,
    85      * i.e. the size of the "entries" array.
    86      * Used to iterate over all entries in the table
    87      */
    88     int size;
    89     /**
    90      * pointer to the array of entries
    91      * Mind that some entries in the array are null (0,0,0,0).
    92      */
    93     const HashEntry* entries;
    94     /**
    95      * the maximum value for the hash minus 1. Always smaller than size.
    96      */
    97     int hashSizeMask;
    98   };
    99 
    100   /**
    101    * @short Fast keyword lookup.
    102    */
    103   class Lookup {
    104   public:
    105     /**
    106      * Find an entry in the table, and return its value (i.e. the value field of HashEntry)
    107      */
    108     static int find(const struct HashTable*, const Identifier&);
    109     static int find(const struct HashTable*, const UChar*, unsigned int len);
    110 
    111     /**
    112      * Find an entry in the table, and return the entry
    113      * This variant gives access to the other attributes of the entry,
    114      * especially the attr field.
    115      */
    116     static const HashEntry* findEntry(const struct HashTable*, const Identifier&);
    117 
    118   };
    119 
    120   class ExecState;
    121   class UString;
     35    // Hash table generated by the create_hash_table script.
     36
     37    struct HashTableValue {
     38        const char* key; // property name
     39        intptr_t value; // integer or function
     40        unsigned char attributes; // JSObject attributes
     41        unsigned char length; // number of arguments for function
     42    };
     43
     44    struct HashEntry {
     45        UString::Rep* key;
     46        union {
     47            intptr_t integerValue;
     48            PrototypeFunction::JSMemberFunction functionValue;
     49        };
     50        unsigned char attributes; // JSObject attributes
     51        unsigned char length; // number of arguments for function
     52    };
     53
     54    struct HashTable {
     55        int hashSizeMask; // Precomputed size for the hash table (minus 1).
     56        const HashTableValue* values; // Fixed values generated by script.
     57        mutable const HashEntry* table; // Table allocated at runtime.
     58
     59        // Find an entry in the table, and return the entry.
     60        ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const
     61        {
     62            if (!table)
     63                createTable();
     64            ASSERT(table);
     65            const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & hashSizeMask];
     66            if (entry->key != identifier.ustring().rep())
     67                return 0;
     68            return entry;
     69        }
     70
     71        // Find an entry in the table, and return the value.
     72        int value(const Identifier& identifier) const
     73        {
     74            const HashEntry* entry = this->entry(identifier);
     75            return entry ? entry->integerValue : -1;
     76        }
     77
     78        // Convert the hash table keys to identifiers.
     79        void createTable() const;
     80    };
     81
    12282  /**
    12383   * @internal
     
    13393
    13494      const HashEntry* entry = slot.staticEntry();
    135       JSValue* val = new PrototypeFunction(exec, entry->params, propertyName, entry->value.functionValue);
    136       thisObj->putDirect(propertyName, val, entry->attr);
     95      JSValue* val = new PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
     96      thisObj->putDirect(propertyName, val, entry->attributes);
    13797      return val;
    13898  }
     
    147107      ThisImp* thisObj = static_cast<ThisImp*>(slot.slotBase());
    148108      const HashEntry* entry = slot.staticEntry();
    149       return thisObj->getValueProperty(exec, entry->value.intValue);
     109      return thisObj->getValueProperty(exec, entry->integerValue);
    150110  }
    151111
     
    171131   */
    172132  template <class ThisImp, class ParentImp>
    173   inline bool getStaticPropertySlot(ExecState* exec, const HashTable* table,
    174                                     ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
    175   {
    176     const HashEntry* entry = Lookup::findEntry(table, propertyName);
     133  inline bool getStaticPropertySlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
     134  {
     135    const HashEntry* entry = table->entry(propertyName);
    177136
    178137    if (!entry) // not found, forward to parent
    179138      return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
    180139
    181     if (entry->attr & Function)
     140    if (entry->attributes & Function)
    182141      slot.setStaticEntry(thisObj, entry, staticFunctionGetter);
    183142    else
     
    193152   */
    194153  template <class ParentImp>
    195   inline bool getStaticFunctionSlot(ExecState* exec, const HashTable* table,
    196                                     JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
    197   {
    198     const HashEntry* entry = Lookup::findEntry(table, propertyName);
     154  inline bool getStaticFunctionSlot(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
     155  {
     156    const HashEntry* entry = table->entry(propertyName);
    199157
    200158    if (!entry) // not found, forward to parent
    201159      return static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
    202160
    203     ASSERT(entry->attr & Function);
     161    ASSERT(entry->attributes & Function);
    204162
    205163    slot.setStaticEntry(thisObj, entry, staticFunctionGetter);
     
    212170   */
    213171  template <class ThisImp, class ParentImp>
    214   inline bool getStaticValueSlot(ExecState* exec, const HashTable* table,
    215                                  ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
    216   {
    217     const HashEntry* entry = Lookup::findEntry(table, propertyName);
     172  inline bool getStaticValueSlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
     173  {
     174    const HashEntry* entry = table->entry(propertyName);
    218175
    219176    if (!entry) // not found, forward to parent
    220177      return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
    221178
    222     ASSERT(!(entry->attr & Function));
     179    ASSERT(!(entry->attributes & Function));
    223180
    224181    slot.setStaticEntry(thisObj, entry, staticValueGetter<ThisImp>);
     
    232189   */
    233190  template <class ThisImp>
    234   inline bool lookupPut(ExecState* exec, const Identifier& propertyName,
    235                         JSValue* value, const HashTable* table, ThisImp* thisObj)
    236   {
    237     const HashEntry* entry = Lookup::findEntry(table, propertyName);
     191  inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj)
     192  {
     193    const HashEntry* entry = table->entry(propertyName);
    238194
    239195    if (!entry)
    240196      return false;
    241197
    242     if (entry->attr & Function) // function: put as override property
     198    if (entry->attributes & Function) // function: put as override property
    243199      thisObj->putDirect(propertyName, value);
    244     else if (!(entry->attr & ReadOnly))
    245       thisObj->putValueProperty(exec, entry->value.intValue, value);
     200    else if (!(entry->attributes & ReadOnly))
     201      thisObj->putValueProperty(exec, entry->integerValue, value);
    246202
    247203    return true;
     
    255211   */
    256212  template <class ThisImp, class ParentImp>
    257   inline void lookupPut(ExecState* exec, const Identifier& propertyName,
    258                         JSValue* value, const HashTable* table, ThisImp* thisObj)
     213  inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj)
    259214  {
    260215    if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
  • trunk/JavaScriptCore/kjs/object.cpp

    r31145 r31147  
    315315  // Look in the static hashtable of properties
    316316  const HashEntry* entry = findPropertyHashEntry(propertyName);
    317   if (entry && entry->attr & DontDelete)
     317  if (entry && entry->attributes & DontDelete)
    318318    return false; // this builtin property can't be deleted
     319  // FIXME: Should the code here actually do some deletion?
    319320  return true;
    320321}
     
    378379const HashEntry* JSObject::findPropertyHashEntry(const Identifier& propertyName) const
    379380{
    380   for (const ClassInfo *info = classInfo(); info; info = info->parentClass) {
    381     if (const HashTable *propHashTable = info->propHashTable) {
    382       if (const HashEntry *e = Lookup::findEntry(propHashTable, propertyName))
    383         return e;
    384     }
    385   }
    386   return 0;
     381    for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
     382        if (const HashTable* propHashTable = info->propHashTable) {
     383            if (const HashEntry* e = propHashTable->entry(propertyName))
     384                return e;
     385        }
     386    }
     387    return 0;
    387388}
    388389
     
    488489  const HashEntry* e = findPropertyHashEntry(propertyName);
    489490  if (e) {
    490     attributes = e->attr;
     491    attributes = e->attributes;
    491492    return true;
    492493  }
     
    497498void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    498499{
    499    _prop.getEnumerablePropertyNames(propertyNames);
    500 
    501   // Add properties from the static hashtable of properties
    502   const ClassInfo *info = classInfo();
    503   while (info) {
    504     if (info->propHashTable) {
    505       int size = info->propHashTable->size;
    506       const HashEntry *e = info->propHashTable->entries;
    507       for (int i = 0; i < size; ++i, ++e) {
    508         if (e->s && !(e->attr & DontEnum))
    509           propertyNames.add(e->s);
    510       }
    511     }
    512     info = info->parentClass;
    513   }
    514   if (_proto->isObject())
    515      static_cast<JSObject*>(_proto)->getPropertyNames(exec, propertyNames);
     500    _prop.getEnumerablePropertyNames(propertyNames);
     501
     502    // Add properties from the static hashtables of properties
     503    for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
     504        const HashTable* table = info->propHashTable;
     505        if (!table)
     506            continue;
     507        if (!table->table)
     508            table->createTable();
     509        ASSERT(table->table);
     510        int hashSizeMask = table->hashSizeMask;
     511        const HashEntry* e = table->table;
     512        for (int i = 0; i <= hashSizeMask; ++i, ++e) {
     513            if (e->key && !(e->attributes & DontEnum))
     514                propertyNames.add(Identifier(e->key));
     515        }
     516    }
     517
     518    if (_proto->isObject())
     519        static_cast<JSObject*>(_proto)->getPropertyNames(exec, propertyNames);
    516520}
    517521
Note: See TracChangeset for help on using the changeset viewer.