Changeset 32609 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Apr 27, 2008, 10:59:07 PM (17 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

2008-04-25 Darin Adler <Darin Adler>

Reviewed by Maciej.

  • fix <rdar://problem/5657459> REGRESSION: JavaScriptCore no longer builds with GCC 4.2 due to pointer aliasing warnings

Fix this by removing the HashTable optimizations that allowed us to share a back end
implementation between hash tables with integers, pointers, RefPtr, and String objects
as keys. The way it worked was incompatible with strict aliasing.

This increases code size. On Mac OS X we'll have to regenerate .order files to avoid
slowing down Safari startup times.

This creates a slight slowdown in SunSpider, mitigated by the following four speedups:

  • speed up array put slightly by moving a branch (was already done for get)
  • speed up symbol table access by adding a function named inlineGet to HashMap and using that in symbolTableGet/Put
  • speed up PropertyNameArray creation by reducing the amount of reference count churn and uniqueness checking when adding names and not doing any allocation at all when building small arrays
  • speed up conversion of strings to floating point numbers by eliminating the malloc/free of the buffer for the ASCII copy of the string; a way to make things even faster would be to change strtod to take a UTF-16 string

Note that there is considerable unused complexity now in HashSet/Map/Table to support
"storage types", which is no longer used. Will do in a separate patch.

  • API/JSCallbackObjectFunctions.h: (KJS::JSCallbackObject<Base>::getPropertyNames): Removed explicit cast to Identifier to take advantage of the new PropertyNameArray::add overload and avoid reference count churn.
  • API/JSObjectRef.cpp: (JSPropertyNameAccumulatorAddName): Ditto.
  • JavaScriptCore.exp: Updated PropertyNameArray::add entry point name.
  • kjs/JSVariableObject.cpp: Removed now-unneeded IdentifierRepHashTraits::nullRepPtr definition (see below). (KJS::JSVariableObject::getPropertyNames): Removed explicit cast to Identifier.
  • kjs/JSVariableObject.h: (KJS::JSVariableObject::symbolTableGet): Use inlineGet for speed. Also changed to do early exit instead of nesting the body inside an if. (KJS::JSVariableObject::symbolTablePut): Ditto.
  • kjs/PropertyNameArray.cpp: (KJS::PropertyNameArray::add): Changed implementation to take a raw pointer instead of a reference to an identifier. Do uniqueness checking by searching the vector when the vector is short, only building the set once the vector is large enough.
  • kjs/PropertyNameArray.h: Added an overload of add for a raw pointer, and made the old add function call that one. Added an addKnownUnique function for use when the new name is known to be different from any other in the array. Changed the vector to have an inline capacity of 20.
  • kjs/SymbolTable.h: Changed IdentifierRepHash to inherit from the default hash for a RefPtr so we don't have to define so much. Added an overload of the hash function for a raw pointer as required by the new RefPtrHashMap. Got rid of the now-unneeded IdentifierRepHashTraits -- the default traits now work fine. Added a definition of empthValueIsZero to SymbolTableIndexHashTraits; not having it was incorrect, but harmless.
  • kjs/array_instance.cpp: (KJS::ArrayInstance::put): Move the maxArrayIndex check inside the branch that checks the index against the length, as done in the get function.
  • kjs/function.cpp: (KJS::globalFuncKJSPrint): Changed to use the new getCString instead of cstring.
  • kjs/internal.cpp: Removed printInfo debugging function, a client of cstring. If we need a debugging function we can easily make a better one and we haven't used this one in a long time.
  • kjs/internal.h: Ditto.
  • kjs/object.cpp: (KJS::JSObject::getPropertyNames): Removed explicit cast to Identifier.
  • kjs/property_map.cpp: (KJS::PropertyMap::getEnumerablePropertyNames): Ditto. Also added a special case for the case where the propertyNames array is empty -- in that case we know we're adding a set of names that are non-overlapping so we can use addKnownUnique.
  • kjs/ustring.cpp: (KJS::UString::getCString): Replaces cstring. Puts the C string into a CStringBuffer, which is a char Vector with an inline capacity. Also returns a boolean to indicate if the converion was lossy, which eliminates the need for a separate is8Bit call. (KJS::UString::toDouble): Changed to call getCString instead of cstring.
  • kjs/ustring.h: Ditto.
  • wtf/HashFunctions.h: Overload the hash and equal functions for RefPtr's default hash to take raw pointers. This works with the changes to RefPtrHashMap to avoid introducing refcount churn.
  • wtf/HashMap.h: Removed special code to convert the deleted value to the empty value when writing a new value into the map. This is now handled elsewhere. (WTF::HashMap::get): Removed code that checks for an empty hash table before calling HashTable::lookup; it's slightly more efficient to do this check inside lookup.
  • wtf/HashTable.h: (WTF::HashTable::isDeletedBucket): Changed to use isDeletedValue instead of using deletedValue and the equality operator. (WTF::HashTable::deleteBucket): Changed to use constructDeletedValue instead of using deletedValue and the assignment operator. (WTF::HashTable::checkKey): Added. Factors out the check for values that are empty or deleted keys that's used in various functions below. (WTF::HashTable::lookup): Changed to use checkKey, check for a 0 table, and also made public for use by RefPtrHashMap. (WTF::HashTable::lookupForWriting): Changed to use checkKey. (WTF::HashTable::fullLookupForWriting): Changed to use checkKey. (WTF::HashTable::add): Changed to use checkKey, and call initializeBucket on a deleted bucket before putting a new entry into it. (WTF::HashTable::addPassingHashCode): Ditto. (WTF::HashTable::deallocateTable): Check isDeletedBucket before calling ~ValueType.
  • wtf/HashTraits.h: Got ridd of all the HashTraits specialization for the integer types, since GeneicHashTraitsBase already deals with integers separately. Put the deleted value support into GenericHashTraitsBase. Changed FloatHashTraits to inherit from GenericHashTraits, and define construct/isDeletedValue rather than deletedValue. Removed the ref and deref functions from RefPtr's HashTraits, and defined construct/isDeletedValue. Eliminated DeletedValueAssigner. Changed PairHashTraits to define construct/isDeletedValue, and also merged PairBaseHashTraits in with PairHashTraits. Got rid of all specialization of HashKeyStorageTraits. We'll remove that, and the needsRef data member, later.
  • wtf/RefPtr.h: Added HashTableDeletedValueType, an enum type with a single value, HashTableDeletedValue. Used that type to make a new constructor to construct deleted values and also added an isHashTableDeletedValue function.
  • wtf/RefPtrHashMap.h: Added RefPtrHashMapRawKeyTranslator and used it to implement the raw pointer functions. This is a way to continue to avoid refcount thrash. We can't use the old way because it depended on the underlying map using a non-RefPtr type. (WTF::HashMap::find): Use find with RefPtrHashMapRawKeyTranslator. (WTF::HashMap::contains): Use contains with RefPtrHashMapRawKeyTranslator. (WTF::HashMap::inlineAdd): Use add with RefPtrHashMapRawKeyTranslator. (WTF::HashMap::get): Removed code that checks for an empty hash table before calling HashTable::lookup; it's slightly more efficient to do this check inside lookup. (WTF::HashMap::inlineGet): Added. Just like get, but marked inline for use in the symbol table code.

WebCore:

2008-04-25 Darin Adler <Darin Adler>

Reviewed by Maciej.

  • update for compatibility with HashTable that no longer has optimization to share implementation between hash tables with integers, pointers, RefPtr, and String objects as keys
  • bindings/js/JSSVGPODTypeWrapper.h: (WebCore::PODTypeReadWriteHashInfo::PODTypeReadWriteHashInfo): Added constructor for HashTableDeletedValue. (WebCore::PODTypeReadWriteHashInfo::isHashTableDeletedValue): Added. (WebCore::PODTypeReadWriteHashInfoTraits::constructDeletedValue): Added. (WebCore::PODTypeReadWriteHashInfoTraits::isDeletedValue): Added.
  • dom/Document.cpp: Made changedDocuments internal to the file rather than a static data member of Document. (WebCore::FormElementKey::ref): Removed unneeded check for deleted value -- this will never be called on a deleted element. (WebCore::FormElementKey::deref): Ditto.
  • dom/Document.h: Added HashTableDeletedValue constructor and isHashTableDeletedValue to FormElementKey. Changed FormElementKeyHashTraits to use construct/isDeletedValue. Got rid of the changedDocuments data member. Changed iconURL to be an inline that returns a const String&.
  • dom/StyledElement.cpp: Changed MappedAttributeKeyTraits to use construct/isDeletedValue.
  • page/mac/AXObjectCacheMac.mm: (WebCore::AXObjectCache::getAXID): Call isDeletedValue instead of deletedValue.
  • platform/SecurityOriginHash.h: Added overload so that SecurityOriginHash can work with raw pointers as well as RefPt (helpful with the new RefPtrHashMap). Eliminated SecurityOriginTraits, since we can now use the default traits. Changed the value of safeToCompareToEmptyOrDeleted to false, since it's not safe to compare a deleted value using this hash function. I don't think it was safe before either; I'm not sure why it didn't cause a problem before.
  • platform/cf/SchedulePair.h: Removed SchedulePairTraits -- custom traits are no longer needed.
  • platform/graphics/FontCache.cpp: (WebCore::FontPlatformDataCacheKey::FontPlatformDataCacheKey): Added constructor for HashTableDeletedValue. (WebCore::FontPlatformDataCacheKey::isHashTableDeletedValue): Added. (WebCore::FontPlatformDataCacheKey::hashTableDeletedSize): Added. (WebCore::FontPlatformDataCacheKeyTraits::constructDeletedValue): Added. (WebCore::FontPlatformDataCacheKeyTraits::isDeletedValue): Added. (WebCore::FontDataCacheKeyTraits::constructDeletedValue): Added. (WebCore::FontDataCacheKeyTraits::isDeletedValue): Added.
  • platform/graphics/IntSizeHash.h: Changed HashTraits<IntSize> to use construct/isDeletedValue.
  • platform/graphics/mac/FontPlatformData.h: (WebCore::FontPlatformData::FontPlatformData): Added constructor for HashTableDeletedValue. (WebCore::FontPlatformData::isHashTableDeletedValue): Added. (WebCore::FontPlatformData::hashTableDeletedFontValue): Added.
  • platform/text/PlatformString.h: (WebCore::String::swap): Added. Avoids any refcount churn when swapping two strings. (WebCore::String::String): Added constructor for HashTableDeletedValue. (WebCore::String::isHashTableDeletedValue): Added. (WebCore::swap): Added. Avoids any refcount churn when swapping two strings.
  • platform/text/StringHash.h: Changed specialization of HashTraits for WebCore::String to use the deleted value now defined in that class and removed the code to do ref/deref. Removed HashKeyStorageTraits specializations.


  • platform/win/COMPtr.h: Changed specialization of HashTraits for COMPtr to use the deleted value now defined in that class and removed the code to do ref/deref. Removed HashKeyStorageTraits specializations. (COMPtr::COMPtr): Added constructor for HashTableDeletedValue. (COMPtr::isHashTableDeletedValue): Added. (COMPtr::query): Removed inline keyword not needed since functions defined in the class definition are automatically marked inline. (COMPtr::hashTableDeletedValue): Added.
  • storage/DatabaseTracker.h: Removed now-unneeded SecurityOriginTraits.
  • storage/LocalStorage.h: Ditto.
  • storage/OriginQuotaManager.h: Ditto.
  • storage/SessionStorage.h: Ditto.
  • svg/SVGAnimatedTemplate.h: (WebCore::SVGAnimatedTypeWrapperKey::SVGAnimatedTypeWrapperKey): Added constructor for HashTableDeletedValue. (WebCore::SVGAnimatedTypeWrapperKey::isHashTableDeletedValue): Added. (WebCore::SVGAnimatedTypeWrapperKeyHashTraits::constructDeletedValue): Added. (WebCore::SVGAnimatedTypeWrapperKeyHashTraits::isDeletedValue): Added.
Location:
trunk/JavaScriptCore/kjs
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/JSVariableObject.cpp

    r32587 r32609  
    3535namespace KJS {
    3636
    37 UString::Rep* IdentifierRepHashTraits::nullRepPtr = &UString::Rep::null; // Didn't want to make a whole source file for just this.
    38 
    3937bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
    4038{
     
    4846{
    4947    SymbolTable::const_iterator end = symbolTable().end();
    50     for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it)
     48    for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
    5149        if ((localStorage()[it->second].attributes & DontEnum) == 0)
    52             propertyNames.add(Identifier(it->first.get()));
    53    
     50            propertyNames.add(it->first.get());
     51    }
     52
    5453    JSObject::getPropertyNames(exec, propertyNames);
    5554}
  • trunk/JavaScriptCore/kjs/JSVariableObject.h

    r32587 r32609  
    9191    inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
    9292    {
    93         size_t index = symbolTable().get(propertyName.ustring().rep());
    94         if (index != missingSymbolMarker()) {
     93        size_t index = symbolTable().inlineGet(propertyName.ustring().rep());
     94        if (index == missingSymbolMarker())
     95            return false;
    9596#ifndef NDEBUG
    96             // During initialization, the variable object needs to advertise that it has certain
    97             // properties, even if they're not ready for access yet. This check verifies that
    98             // no one tries to access such a property.
    99            
    100             // In a release build, we optimize this check away and just return an invalid pointer.
    101             // There's no harm in an invalid pointer, since no one dereferences it.
    102             if (index >= d->localStorage.size()) {
    103                 slot.setUngettable(this);
    104                 return true;
    105             }
    106 #endif
    107             slot.setValueSlot(this, &d->localStorage[index].value);
     97        // During initialization, the variable object needs to advertise that it has certain
     98        // properties, even if they're not ready for access yet. This check verifies that
     99        // no one tries to access such a property. In a release build, we optimize this check
     100        // away and just return an invalid pointer. There's no harm in an invalid pointer,
     101        // since no one dereferences it.
     102        if (index >= d->localStorage.size()) {
     103            slot.setUngettable(this);
    108104            return true;
    109105        }
    110         return false;
     106#endif
     107        slot.setValueSlot(this, &d->localStorage[index].value);
     108        return true;
    111109    }
    112110
    113111    inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value)
    114112    {
    115         size_t index = symbolTable().get(propertyName.ustring().rep());
     113        size_t index = symbolTable().inlineGet(propertyName.ustring().rep());
    116114        if (index == missingSymbolMarker())
    117115            return false;
     
    133131        return true;
    134132    }
    135    
     133
    136134    inline bool JSVariableObject::symbolTableInsert(const Identifier& propertyName, JSValue* value, unsigned attributes)
    137135    {
    138136        if (symbolTable().get(propertyName.ustring().rep()) != missingSymbolMarker())
    139137            return false;
    140 
    141         ASSERT((attributes & DontDelete) != 0);
    142138        size_t localStorageIndex = d->localStorage.size();
    143139        d->localStorage.append(LocalStorageEntry(value, attributes));
     
    145141        return true;
    146142    }
     143
    147144} // namespace KJS
    148145
  • trunk/JavaScriptCore/kjs/PropertyNameArray.cpp

    r29663 r32609  
    11// -*- mode: c++; c-basic-offset: 4 -*-
    22/*
    3  *  Copyright (C) 2006 Apple Computer, Inc
     3 *  Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    2525namespace KJS {
    2626
    27 void PropertyNameArray::add(const Identifier& ident)
     27static const size_t setThreshold = 20;
     28
     29void PropertyNameArray::add(UString::Rep* identifier)
    2830{
    29     if (!m_set.add(ident.ustring().rep()).second)
    30         return;
    31    
    32     m_vector.append(ident);
     31    ASSERT(identifier->identifierTable);
     32
     33    size_t size = m_vector.size();
     34    if (size < setThreshold) {
     35        for (size_t i = 0; i < size; ++i) {
     36            if (identifier == m_vector[i].ustring().rep())
     37                return;
     38        }
     39    } else {
     40        if (m_set.isEmpty()) {
     41            for (size_t i = 0; i < size; ++i)
     42                m_set.add(m_vector[i].ustring().rep());
     43        }
     44        if (!m_set.add(identifier).second)
     45            return;
     46    }
     47
     48    m_vector.append(identifier);
    3349}
    3450
    35 void PropertyNameArray::swap(PropertyNameArray& other)
    36 {
    37     m_vector.swap(other.m_vector);
    38     m_set.swap(other.m_set);
    39 }
    40 
    41 
    4251} // namespace KJS
    43 
  • trunk/JavaScriptCore/kjs/PropertyNameArray.h

    r29663 r32609  
    11// -*- mode: c++; c-basic-offset: 4 -*-
    22/*
    3  *  Copyright (C) 2006 Apple Computer, Inc
     3 *  Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    2424
    2525#include "identifier.h"
    26 
    2726#include <wtf/HashSet.h>
    2827#include <wtf/Vector.h>
     
    3534        typedef Vector<Identifier>::const_iterator const_iterator;
    3635
    37         void add(const Identifier&);
     36        void add(const Identifier& identifier) { add(identifier.ustring().rep()); }
     37        void add(UString::Rep*);
     38        void addKnownUnique(UString::Rep* identifier) { m_vector.append(identifier); }
    3839        const_iterator begin() const { return m_vector.begin(); }
    3940        const_iterator end() const { return m_vector.end(); }
     
    4344        const Identifier& operator[](unsigned i) const { return m_vector[i]; }
    4445
    45         void swap(PropertyNameArray&);
    4646    private:
    4747        typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet;
     48
     49        Vector<Identifier, 20> m_vector;
    4850        IdentifierSet m_set;
    49         Vector<Identifier> m_vector;
    5051    };
    51 
    5252
    5353} // namespace KJS
  • trunk/JavaScriptCore/kjs/SymbolTable.h

    r32449 r32609  
    3535namespace KJS {
    3636
    37     struct IdentifierRepHash {
     37    struct IdentifierRepHash : PtrHash<RefPtr<UString::Rep> > {
    3838        static unsigned hash(const RefPtr<UString::Rep>& key) { return key->computedHash(); }
    39         static bool equal(const RefPtr<UString::Rep>& a, const RefPtr<UString::Rep>& b) { return a == b; }
    40         static const bool safeToCompareToEmptyOrDeleted = true;
    41     };
    42 
    43     struct IdentifierRepHashTraits : HashTraits<RefPtr<UString::Rep> > {
    44         static const RefPtr<UString::Rep>& deletedValue()
    45         {
    46             return *reinterpret_cast<RefPtr<UString::Rep>*>(&nullRepPtr);
    47         }
    48 
    49     private:
    50         static UString::Rep* nullRepPtr;
     39        static unsigned hash(UString::Rep* key) { return key->computedHash(); }
    5140    };
    5241
     
    5443
    5544    struct SymbolTableIndexHashTraits : HashTraits<size_t> {
     45        static const bool emptyValueIsZero = false;
    5646        static size_t emptyValue() { return missingSymbolMarker(); }
    5747    };
    5848
    59     typedef HashMap<RefPtr<UString::Rep>, size_t, IdentifierRepHash, IdentifierRepHashTraits, SymbolTableIndexHashTraits> SymbolTable;
     49    typedef HashMap<RefPtr<UString::Rep>, size_t, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable;
    6050
    6151} // namespace KJS
  • trunk/JavaScriptCore/kjs/array_instance.cpp

    r32220 r32609  
    208208void ArrayInstance::put(ExecState* exec, unsigned i, JSValue* value)
    209209{
    210     if (i > maxArrayIndex) {
    211         put(exec, Identifier::from(i), value);
    212         return;
    213     }
    214 
    215     ArrayStorage* storage = m_storage;
    216 
    217210    unsigned length = m_length;
    218211    if (i >= length) {
     212        if (i > maxArrayIndex) {
     213            put(exec, Identifier::from(i), value);
     214            return;
     215        }
    219216        length = i + 1;
    220217        m_length = length;
    221218    }
     219
     220    ArrayStorage* storage = m_storage;
    222221
    223222    if (i < m_vectorLength) {
  • trunk/JavaScriptCore/kjs/function.cpp

    r31962 r32609  
    33 *  Copyright (C) 1999-2002 Harri Porten ([email protected])
    44 *  Copyright (C) 2001 Peter Kelly ([email protected])
    5  *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     5 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    66 *  Copyright (C) 2007 Cameron Zwarich ([email protected])
    77 *  Copyright (C) 2007 Maks Orlovich
     
    876876JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, const List& args)
    877877{
    878     puts(args[0]->toString(exec).ascii());
     878    CStringBuffer string;
     879    args[0]->toString(exec).getCString(string);
     880    puts(string.data());
    879881    return jsUndefined();
    880882}
  • trunk/JavaScriptCore/kjs/internal.cpp

    r29817 r32609  
    243243}
    244244
    245 // ------------------------------ global functions -----------------------------
    246 
    247 #ifndef NDEBUG
    248 #include <stdio.h>
    249 void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
    250 {
    251   if (!o)
    252     fprintf(stderr, "KJS: %s: (null)", s);
    253   else {
    254     JSValue *v = o;
    255 
    256     UString name;
    257     switch (v->type()) {
    258     case UnspecifiedType:
    259       name = "Unspecified";
    260       break;
    261     case UndefinedType:
    262       name = "Undefined";
    263       break;
    264     case NullType:
    265       name = "Null";
    266       break;
    267     case BooleanType:
    268       name = "Boolean";
    269       break;
    270     case StringType:
    271       name = "String";
    272       break;
    273     case NumberType:
    274       name = "Number";
    275       break;
    276     case ObjectType:
    277       name = static_cast<JSObject *>(v)->className();
    278       if (name.isNull())
    279         name = "(unknown class)";
    280       break;
    281     case GetterSetterType:
    282       name = "GetterSetter";
    283       break;
    284     }
    285     UString vString = v->toString(exec);
    286     if ( vString.size() > 50 )
    287       vString = vString.substr( 0, 50 ) + "...";
    288     // Can't use two UString::ascii() in the same fprintf call
    289     CString tempString( vString.cstring() );
    290 
    291     fprintf(stderr, "KJS: %s: %s : %s (%p)",
    292             s, tempString.c_str(), name.ascii(), (void*)v);
    293 
    294     if (lineno >= 0)
    295       fprintf(stderr, ", line %d\n",lineno);
    296     else
    297       fprintf(stderr, "\n");
    298   }
    299 }
    300 #endif
    301 
    302 }
     245}
  • trunk/JavaScriptCore/kjs/internal.h

    r30679 r32609  
    109109  };
    110110
    111 #ifndef NDEBUG
    112   void printInfo(ExecState *exec, const char *s, JSValue *, int lineno = -1);
    113 #endif
    114 
    115111} // namespace
    116112
  • trunk/JavaScriptCore/kjs/object.cpp

    r31962 r32609  
    11// -*- c-basic-offset: 2 -*-
    22/*
    3  *  This file is part of the KDE libraries
    43 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    54 *  Copyright (C) 2001 Peter Kelly ([email protected])
    6  *  Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
     5 *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
    76 *  Copyright (C) 2007 Eric Seidel ([email protected])
    87 *
     
    572571        for (int i = 0; i <= hashSizeMask; ++i, ++e) {
    573572            if (e->key && !(e->attributes & DontEnum))
    574                 propertyNames.add(Identifier(e->key));
     573                propertyNames.add(e->key);
    575574        }
    576575    }
  • trunk/JavaScriptCore/kjs/property_map.cpp

    r32587 r32609  
    665665        UString::Rep* key = m_singleEntryKey;
    666666        if (key && !(m_singleEntryAttributes & DontEnum))
    667             propertyNames.add(Identifier(key));
     667            propertyNames.add(key);
    668668#endif
    669669        return;
     
    684684            }
    685685        }
    686         for (int k = 0; k < i; ++k)
    687             propertyNames.add(Identifier(a[k]->key));
     686        if (!propertyNames.size()) {
     687            for (int k = 0; k < i; ++k)
     688                propertyNames.addKnownUnique(a[k]->key);
     689        } else {
     690            for (int k = 0; k < i; ++k)
     691                propertyNames.add(a[k]->key);
     692        }
    688693        return;
    689694    }
     
    705710    // Put the keys of the sorted entries into the list.
    706711    for (Entry** q = sortedEnumerables.data(); q != p; ++q)
    707         propertyNames.add(Identifier(q[0]->key));
     712        propertyNames.add(q[0]->key);
    708713}
    709714
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r32242 r32609  
    22/*
    33 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    4  *  Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    55 *  Copyright (C) 2007 Cameron Zwarich ([email protected])
    66 *
     
    862862}
    863863
    864 CString UString::cstring() const
    865 {
    866   int length = size();
    867   int neededSize = length + 1;
    868   char* buf = new char[neededSize];
    869  
    870   const UChar* p = data();
    871   char* q = buf;
    872   const UChar* limit = p + length;
    873   while (p != limit) {
    874     *q = static_cast<char>(p[0]);
    875     ++p;
    876     ++q;
    877   }
    878   *q = '\0';
    879  
    880   return CString::adopt(buf, length);
     864bool UString::getCString(CStringBuffer& buffer) const
     865{
     866    int length = size();
     867    int neededSize = length + 1;
     868    buffer.resize(neededSize);
     869    char* buf = buffer.data();
     870 
     871    UChar ored = 0;
     872    const UChar* p = data();
     873    char* q = buf;
     874    const UChar* limit = p + length;
     875    while (p != limit) {
     876        UChar c = p[0];
     877        ored |= c;
     878        *q = static_cast<char>(c);
     879        ++p;
     880        ++q;
     881    }
     882    *q = '\0';
     883 
     884    return !(ored & 0xFF00);
    881885}
    882886
     
    958962
    959963  // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk
    960   // after the number, so is8Bit is too strict a check.
    961   if (!is8Bit())
     964  // after the number, so this is too strict a check.
     965  CStringBuffer s;
     966  if (!getCString(s))
    962967    return NaN;
    963 
    964   CString s = cstring();
    965   const char* c = s.c_str();
     968  const char* c = s.data();
    966969
    967970  // skip leading white space
  • trunk/JavaScriptCore/kjs/ustring.h

    r32319 r32609  
    22/*
    33 *  Copyright (C) 1999-2000 Harri Porten ([email protected])
    4  *  Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    7777  };
    7878
     79  typedef Vector<char, 32> CStringBuffer;
     80
    7981  /**
    8082   * @short Unicode string class
     
    220222    /**
    221223     * @return The string converted to the 8-bit string type CString().
    222      * This method is not Unicode safe and shouldn't be used unless the string
    223      * is known to be ASCII.
    224      */
    225     CString cstring() const;
    226     /**
    227      * Convert the Unicode string to plain ASCII chars chopping of any higher
     224     * Returns false if any character is non-ASCII.
     225     */
     226    bool getCString(CStringBuffer&) const;
     227
     228    /**
     229     * Convert the Unicode string to plain ASCII chars chopping off any higher
    228230     * bytes. This method should only be used for *debugging* purposes as it
    229231     * is neither Unicode safe nor free from side effects nor thread-safe.
Note: See TracChangeset for help on using the changeset viewer.