Fix <rdar://5954749> Assertion failure due to HashTable's use of operator&

JavaScriptCore:

        Fix <rdar://5954749> Assertion failure due to HashTable's use of
        operator&

        HashTable was passing &value to constructDeletedValue, which in
        classes like WebCore::COMPtr would cause an assertion. We now pass
        value by reference instead of by address so that the HashTraits
        implementations have more flexibility in constructing the deleted
        value.

        Reviewed by Ada Chan.

        * VM/CodeGenerator.h: Updated for changes to HashTraits.
        * wtf/HashTable.h:
        (WTF::::deleteBucket): Changed to pass bucket by reference instead of
        by address.
        (WTF::::checkKey): Ditto.
        * wtf/HashTraits.h:
        (WTF::): Updated HashTraits for HashTable change.

WebCore:

        Fix <rdar://5954749> Assertion failure due to HashTable's use of
        operator&

        Reviewed by Ada Chan.

        * bindings/js/JSSVGPODTypeWrapper.h:
        * dom/Document.h:
        * dom/StyledElement.cpp:
        * platform/graphics/FontCache.cpp:
        * platform/graphics/IntSizeHash.h:
        (WTF::):
        * platform/text/StringHash.h:
        * platform/win/COMPtr.h:
        * svg/SVGAnimatedTemplate.h:
        Updated all custom HashTraits for HashTable changes.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34891 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 83b8867..b99609e 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,24 @@
+2008-06-30  Adam Roben  <aroben@apple.com>
+
+        Fix <rdar://5954749> Assertion failure due to HashTable's use of
+        operator&
+
+        HashTable was passing &value to constructDeletedValue, which in
+        classes like WebCore::COMPtr would cause an assertion. We now pass
+        value by reference instead of by address so that the HashTraits
+        implementations have more flexibility in constructing the deleted
+        value.
+
+        Reviewed by Ada Chan.
+
+        * VM/CodeGenerator.h: Updated for changes to HashTraits.
+        * wtf/HashTable.h:
+        (WTF::::deleteBucket): Changed to pass bucket by reference instead of
+        by address.
+        (WTF::::checkKey): Ditto.
+        * wtf/HashTraits.h:
+        (WTF::): Updated HashTraits for HashTable change.
+
 2008-06-30  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Cameron Zwarich.
diff --git a/JavaScriptCore/VM/CodeGenerator.h b/JavaScriptCore/VM/CodeGenerator.h
index 5bb55cb..daf6fec 100644
--- a/JavaScriptCore/VM/CodeGenerator.h
+++ b/JavaScriptCore/VM/CodeGenerator.h
@@ -295,7 +295,7 @@
 
         PassRefPtr<LabelID> emitComplexJumpScopes(LabelID* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
         struct JSValueHashTraits : HashTraits<JSValue*> {
-            static void constructDeletedValue(JSValue** slot) { *slot = JSImmediate::impossibleValue(); }
+            static void constructDeletedValue(JSValue*& slot) { slot = JSImmediate::impossibleValue(); }
             static bool isDeletedValue(JSValue* value) { return value == JSImmediate::impossibleValue(); }
         };
 
diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h
index d31b9c6..cad36b4 100644
--- a/JavaScriptCore/wtf/HashTable.h
+++ b/JavaScriptCore/wtf/HashTable.h
@@ -364,7 +364,7 @@
         void reinsert(ValueType&);
 
         static void initializeBucket(ValueType& bucket) { new (&bucket) ValueType(Traits::emptyValue()); }
-        static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Traits::constructDeletedValue(&bucket); }
+        static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Traits::constructDeletedValue(bucket); }
 
         FullLookupType makeLookupResult(ValueType* position, bool found, unsigned hash)
             { return FullLookupType(LookupType(position, found), hash); }
@@ -444,7 +444,7 @@
         ASSERT(!HashTranslator::equal(KeyTraits::emptyValue(), key));
         ValueType deletedValue = Traits::emptyValue();
         deletedValue.~ValueType();
-        Traits::constructDeletedValue(&deletedValue);
+        Traits::constructDeletedValue(deletedValue);
         ASSERT(!HashTranslator::equal(Extractor::extract(deletedValue), key));
         new (&deletedValue) ValueType(Traits::emptyValue());
     }
diff --git a/JavaScriptCore/wtf/HashTraits.h b/JavaScriptCore/wtf/HashTraits.h
index 2627831..f5b0707 100644
--- a/JavaScriptCore/wtf/HashTraits.h
+++ b/JavaScriptCore/wtf/HashTraits.h
@@ -86,7 +86,7 @@
     template<typename T> struct GenericHashTraitsBase<true, T> {
         static const bool emptyValueIsZero = true;
         static const bool needsDestruction = false;
-        static void constructDeletedValue(T* slot) { *slot = static_cast<T>(-1); }
+        static void constructDeletedValue(T& slot) { slot = static_cast<T>(-1); }
         static bool isDeletedValue(T value) { return value == static_cast<T>(-1); }
     };
 
@@ -100,7 +100,7 @@
     template<typename T> struct FloatHashTraits : GenericHashTraits<T> {
         static const bool needsDestruction = false;
         static T emptyValue() { return std::numeric_limits<T>::infinity(); }
-        static void constructDeletedValue(T* slot) { *slot = -std::numeric_limits<T>::infinity(); }
+        static void constructDeletedValue(T& slot) { slot = -std::numeric_limits<T>::infinity(); }
         static bool isDeletedValue(T value) { return value == -std::numeric_limits<T>::infinity(); }
     };
 
@@ -110,13 +110,13 @@
     template<typename P> struct HashTraits<P*> : GenericHashTraits<P*> {
         static const bool emptyValueIsZero = true;
         static const bool needsDestruction = false;
-        static void constructDeletedValue(P** slot) { *slot = reinterpret_cast<P*>(-1); }
+        static void constructDeletedValue(P*& slot) { slot = reinterpret_cast<P*>(-1); }
         static bool isDeletedValue(P* value) { return value == reinterpret_cast<P*>(-1); }
     };
 
     template<typename P> struct HashTraits<RefPtr<P> > : GenericHashTraits<RefPtr<P> > {
         static const bool emptyValueIsZero = true;
-        static void constructDeletedValue(RefPtr<P>* slot) { new (slot) RefPtr<P>(HashTableDeletedValue); }
+        static void constructDeletedValue(RefPtr<P>& slot) { new (&slot) RefPtr<P>(HashTableDeletedValue); }
         static bool isDeletedValue(const RefPtr<P>& value) { return value.isHashTableDeletedValue(); }
     };
 
@@ -133,7 +133,7 @@
 
         static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
 
-        static void constructDeletedValue(TraitType* slot) { FirstTraits::constructDeletedValue(&slot->first); }
+        static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
         static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
     };
 
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3691bec..c159a77 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,21 @@
+2008-06-30  Adam Roben  <aroben@apple.com>
+
+        Fix <rdar://5954749> Assertion failure due to HashTable's use of
+        operator&
+
+        Reviewed by Ada Chan.
+
+        * bindings/js/JSSVGPODTypeWrapper.h:
+        * dom/Document.h:
+        * dom/StyledElement.cpp:
+        * platform/graphics/FontCache.cpp:
+        * platform/graphics/IntSizeHash.h:
+        (WTF::):
+        * platform/text/StringHash.h:
+        * platform/win/COMPtr.h:
+        * svg/SVGAnimatedTemplate.h:
+        Updated all custom HashTraits for HashTable changes.
+
 2008-06-30  Simon Hausmann  <hausmann@webkit.org>
 
         Fix the Qt build.
diff --git a/WebCore/bindings/js/JSSVGPODTypeWrapper.h b/WebCore/bindings/js/JSSVGPODTypeWrapper.h
index 545410a..ae06a96 100644
--- a/WebCore/bindings/js/JSSVGPODTypeWrapper.h
+++ b/WebCore/bindings/js/JSSVGPODTypeWrapper.h
@@ -232,9 +232,9 @@
         return key;
     }
 
-    static void constructDeletedValue(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>* slot)
+    static void constructDeletedValue(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& slot)
     {
-        new (slot) PODTypeReadWriteHashInfo<PODType, PODTypeCreator>(WTF::HashTableDeletedValue);
+        new (&slot) PODTypeReadWriteHashInfo<PODType, PODTypeCreator>(WTF::HashTableDeletedValue);
     }
     static bool isDeletedValue(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& value)
     {
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 6a805f9..0e8ab1a 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -161,7 +161,7 @@
 };
 
 struct FormElementKeyHashTraits : WTF::GenericHashTraits<FormElementKey> {
-    static void constructDeletedValue(FormElementKey* slot) { new (slot) FormElementKey(WTF::HashTableDeletedValue); }
+    static void constructDeletedValue(FormElementKey& slot) { new (&slot) FormElementKey(WTF::HashTableDeletedValue); }
     static bool isDeletedValue(const FormElementKey& value) { return value.isHashTableDeletedValue(); }
 };
 
diff --git a/WebCore/dom/StyledElement.cpp b/WebCore/dom/StyledElement.cpp
index 51e9e27..dec9f2c 100644
--- a/WebCore/dom/StyledElement.cpp
+++ b/WebCore/dom/StyledElement.cpp
@@ -50,7 +50,7 @@
 struct MappedAttributeKeyTraits : WTF::GenericHashTraits<MappedAttributeKey> {
     static const bool emptyValueIsZero = true;
     static const bool needsDestruction = false;
-    static void constructDeletedValue(MappedAttributeKey* slot) { slot->type = eLastEntry; }
+    static void constructDeletedValue(MappedAttributeKey& slot) { slot.type = eLastEntry; }
     static bool isDeletedValue(const MappedAttributeKey& value) { return value.type == eLastEntry; }
 };
 
diff --git a/WebCore/platform/graphics/FontCache.cpp b/WebCore/platform/graphics/FontCache.cpp
index d91fb89..32d75ec 100644
--- a/WebCore/platform/graphics/FontCache.cpp
+++ b/WebCore/platform/graphics/FontCache.cpp
@@ -107,9 +107,9 @@
         static FontPlatformDataCacheKey key(nullAtom);
         return key;
     }
-    static void constructDeletedValue(FontPlatformDataCacheKey* slot)
+    static void constructDeletedValue(FontPlatformDataCacheKey& slot)
     {
-        new (slot) FontPlatformDataCacheKey(HashTableDeletedValue);
+        new (&slot) FontPlatformDataCacheKey(HashTableDeletedValue);
     }
     static bool isDeletedValue(const FontPlatformDataCacheKey& value)
     {
@@ -205,9 +205,9 @@
         static FontPlatformData key;
         return key;
     }
-    static void constructDeletedValue(FontPlatformData* slot)
+    static void constructDeletedValue(FontPlatformData& slot)
     {
-        new (slot) FontPlatformData(HashTableDeletedValue);
+        new (&slot) FontPlatformData(HashTableDeletedValue);
     }
     static bool isDeletedValue(const FontPlatformData& value)
     {
diff --git a/WebCore/platform/graphics/IntSizeHash.h b/WebCore/platform/graphics/IntSizeHash.h
index 2c524f9..ad6eac3 100644
--- a/WebCore/platform/graphics/IntSizeHash.h
+++ b/WebCore/platform/graphics/IntSizeHash.h
@@ -38,7 +38,7 @@
     template<> struct HashTraits<IntSize> : GenericHashTraits<IntSize> {
         static const bool emptyValueIsZero = true;
         static const bool needsDestruction = false;
-        static void constructDeletedValue(IntSize* slot) { new (slot) IntSize(-1, -1); }
+        static void constructDeletedValue(IntSize& slot) { new (&slot) IntSize(-1, -1); }
         static bool isDeletedValue(const IntSize& value) { return value.width() == -1 && value.height() == -1; }
     };
 } // namespace WTF
diff --git a/WebCore/platform/text/StringHash.h b/WebCore/platform/text/StringHash.h
index 1eba8c7..c6e08a6 100644
--- a/WebCore/platform/text/StringHash.h
+++ b/WebCore/platform/text/StringHash.h
@@ -233,7 +233,7 @@
 
     template<> struct HashTraits<WebCore::String> : GenericHashTraits<WebCore::String> {
         static const bool emptyValueIsZero = true;
-        static void constructDeletedValue(WebCore::String* slot) { new (slot) WebCore::String(HashTableDeletedValue); }
+        static void constructDeletedValue(WebCore::String& slot) { new (&slot) WebCore::String(HashTableDeletedValue); }
         static bool isDeletedValue(const WebCore::String& slot) { return slot.isHashTableDeletedValue(); }
     };
 
diff --git a/WebCore/platform/win/COMPtr.h b/WebCore/platform/win/COMPtr.h
index 67f4da2..784495a 100644
--- a/WebCore/platform/win/COMPtr.h
+++ b/WebCore/platform/win/COMPtr.h
@@ -198,7 +198,7 @@
 
     template<typename P> struct HashTraits<COMPtr<P> > : GenericHashTraits<COMPtr<P> > {
         static const bool emptyValueIsZero = true;
-        static void constructDeletedValue(P** slot) { *slot = reinterpret_cast<P*>(-1); }
+        static void constructDeletedValue(COMPtr<P>& slot) { slot.releaseRef(); *&slot = reinterpret_cast<P*>(-1); }
         static bool isDeletedValue(const COMPtr<P>& value) { return value == reinterpret_cast<P*>(-1); }
     };
 
diff --git a/WebCore/svg/SVGAnimatedTemplate.h b/WebCore/svg/SVGAnimatedTemplate.h
index 3786100..b30bc69 100644
--- a/WebCore/svg/SVGAnimatedTemplate.h
+++ b/WebCore/svg/SVGAnimatedTemplate.h
@@ -90,9 +90,9 @@
     struct SVGAnimatedTypeWrapperKeyHashTraits : WTF::GenericHashTraits<SVGAnimatedTypeWrapperKey> {
         static const bool emptyValueIsZero = true;
         
-        static void constructDeletedValue(SVGAnimatedTypeWrapperKey* slot)
+        static void constructDeletedValue(SVGAnimatedTypeWrapperKey& slot)
         {
-            new (slot) SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValue);
+            new (&slot) SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValue);
         }
         static bool isDeletedValue(const SVGAnimatedTypeWrapperKey& value)
         {