diff --git a/caps/src/nsPrincipal.cpp b/caps/src/nsPrincipal.cpp index 0d08f0015a02..97005d838ad8 100644 --- a/caps/src/nsPrincipal.cpp +++ b/caps/src/nsPrincipal.cpp @@ -60,7 +60,6 @@ #include "nsPrincipal.h" #include "mozilla/Preferences.h" -#include "mozilla/HashFunctions.h" using namespace mozilla; @@ -807,7 +806,7 @@ nsPrincipal::GetHashValue(PRUint32* aValue) // If there is a certificate, it takes precendence over the codebase. if (mCert) { - *aValue = HashString(mCert->fingerprint); + *aValue = nsCRT::HashCode(mCert->fingerprint.get()); } else { *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this); diff --git a/content/base/src/nsAttrValue.cpp b/content/base/src/nsAttrValue.cpp index dd69bec42f73..53dffd927e4d 100644 --- a/content/base/src/nsAttrValue.cpp +++ b/content/base/src/nsAttrValue.cpp @@ -51,9 +51,10 @@ #include "nsContentUtils.h" #include "nsReadableUtils.h" #include "prprf.h" -#include "mozilla/HashFunctions.h" -using namespace mozilla; +namespace css = mozilla::css; + +using mozilla::SVGAttrValueWrapper; #define MISC_STR_PTR(_cont) \ reinterpret_cast((_cont)->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK) @@ -391,7 +392,7 @@ nsAttrValue::SetTo(const nsSVGLength2& aValue, const nsAString* aSerialized) } void -nsAttrValue::SetTo(const SVGLengthList& aValue, +nsAttrValue::SetTo(const mozilla::SVGLengthList& aValue, const nsAString* aSerialized) { // While an empty string will parse as a length list, there's no need to store @@ -403,7 +404,7 @@ nsAttrValue::SetTo(const SVGLengthList& aValue, } void -nsAttrValue::SetTo(const SVGNumberList& aValue, +nsAttrValue::SetTo(const mozilla::SVGNumberList& aValue, const nsAString* aSerialized) { // While an empty string will parse as a number list, there's no need to store @@ -421,7 +422,7 @@ nsAttrValue::SetTo(const nsSVGNumberPair& aValue, const nsAString* aSerialized) } void -nsAttrValue::SetTo(const SVGPathData& aValue, +nsAttrValue::SetTo(const mozilla::SVGPathData& aValue, const nsAString* aSerialized) { // While an empty string will parse as path data, there's no need to store it @@ -433,7 +434,7 @@ nsAttrValue::SetTo(const SVGPathData& aValue, } void -nsAttrValue::SetTo(const SVGPointList& aValue, +nsAttrValue::SetTo(const mozilla::SVGPointList& aValue, const nsAString* aSerialized) { // While an empty string will parse as a point list, there's no need to store @@ -445,14 +446,14 @@ nsAttrValue::SetTo(const SVGPointList& aValue, } void -nsAttrValue::SetTo(const SVGAnimatedPreserveAspectRatio& aValue, +nsAttrValue::SetTo(const mozilla::SVGAnimatedPreserveAspectRatio& aValue, const nsAString* aSerialized) { SetSVGType(eSVGPreserveAspectRatio, &aValue, aSerialized); } void -nsAttrValue::SetTo(const SVGStringList& aValue, +nsAttrValue::SetTo(const mozilla::SVGStringList& aValue, const nsAString* aSerialized) { // While an empty string will parse as a string list, there's no need to store @@ -464,7 +465,7 @@ nsAttrValue::SetTo(const SVGStringList& aValue, } void -nsAttrValue::SetTo(const SVGTransformList& aValue, +nsAttrValue::SetTo(const mozilla::SVGTransformList& aValue, const nsAString* aSerialized) { // While an empty string will parse as a transform list, there's no need to @@ -763,7 +764,7 @@ nsAttrValue::HashValue() const nsStringBuffer* str = static_cast(GetPtr()); if (str) { PRUint32 len = str->StorageSize()/sizeof(PRUnichar) - 1; - return HashString(static_cast(str->Data()), len); + return nsCRT::HashCode(static_cast(str->Data()), len); } return 0; @@ -811,14 +812,14 @@ nsAttrValue::HashValue() const } case eAtomArray: { - PRUint32 hash = 0; + PRUint32 retval = 0; PRUint32 count = cont->mAtomArray->Length(); for (nsCOMPtr *cur = cont->mAtomArray->Elements(), *end = cur + count; cur != end; ++cur) { - hash = AddToHash(hash, cur->get()); + retval ^= NS_PTR_TO_INT32(cur->get()); } - return hash; + return retval; } case eDoubleValue: { diff --git a/content/base/src/nsContentList.h b/content/base/src/nsContentList.h index 753a21c01795..425b1e3db01b 100644 --- a/content/base/src/nsContentList.h +++ b/content/base/src/nsContentList.h @@ -55,8 +55,8 @@ #include "nsINameSpaceManager.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" +#include "nsCRT.h" #include "nsHashKeys.h" -#include "mozilla/HashFunctions.h" // Magic namespace id that means "match all namespaces". This is // negative so it won't collide with actual namespace constants. @@ -204,8 +204,10 @@ struct nsContentListKey inline PRUint32 GetHash(void) const { - PRUint32 hash = mozilla::HashString(mTagname); - return mozilla::AddToHash(hash, mRootNode, mMatchNameSpaceId); + return + HashString(mTagname) ^ + (NS_PTR_TO_INT32(mRootNode) << 12) ^ + (mMatchNameSpaceId << 24); } nsINode* const mRootNode; // Weak ref @@ -488,8 +490,8 @@ public: PRUint32 GetHash(void) const { - PRUint32 hash = mozilla::HashString(mString); - return mozilla::AddToHash(hash, mRootNode, mFunc); + return NS_PTR_TO_INT32(mRootNode) ^ (NS_PTR_TO_INT32(mFunc) << 12) ^ + nsCRT::HashCode(mString.BeginReading(), mString.Length()); } private: diff --git a/content/base/src/nsDOMAttributeMap.h b/content/base/src/nsDOMAttributeMap.h index 28b94e6e4f13..08d65d3d694c 100644 --- a/content/base/src/nsDOMAttributeMap.h +++ b/content/base/src/nsDOMAttributeMap.h @@ -112,7 +112,8 @@ public: if (!aKey) return 0; - return mozilla::HashGeneric(aKey->mNamespaceID, aKey->mLocalName); + return PR_ROTATE_LEFT32(static_cast(aKey->mNamespaceID), 4) ^ + NS_PTR_TO_INT32(aKey->mLocalName); } enum { ALLOW_MEMMOVE = true }; diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index dac260b27b28..825643585533 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -238,7 +238,8 @@ public: static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { - return mozilla::HashGeneric(aKey->mCallback, aKey->mData); + return (NS_PTR_TO_INT32(aKey->mCallback) >> 2) ^ + (NS_PTR_TO_INT32(aKey->mData)); } enum { ALLOW_MEMMOVE = true }; diff --git a/content/base/src/nsMappedAttributes.cpp b/content/base/src/nsMappedAttributes.cpp index 7dde436da9f0..1ebb46d1a00a 100644 --- a/content/base/src/nsMappedAttributes.cpp +++ b/content/base/src/nsMappedAttributes.cpp @@ -45,9 +45,6 @@ #include "nsHTMLStyleSheet.h" #include "nsRuleWalker.h" #include "prmem.h" -#include "mozilla/HashFunctions.h" - -using namespace mozilla; nsMappedAttributes::nsMappedAttributes(nsHTMLStyleSheet* aSheet, nsMapRuleToAttributesFunc aMapRuleFunc) @@ -179,16 +176,14 @@ nsMappedAttributes::Equals(const nsMappedAttributes* aOther) const PRUint32 nsMappedAttributes::HashValue() const { - PRUint32 hash = HashGeneric(mRuleMapper); + PRUint32 value = NS_PTR_TO_INT32(mRuleMapper); PRUint32 i; for (i = 0; i < mAttrCount; ++i) { - hash = AddToHash(hash, - Attrs()[i].mName.HashValue(), - Attrs()[i].mValue.HashValue()); + value ^= Attrs()[i].mName.HashValue() ^ Attrs()[i].mValue.HashValue(); } - return hash; + return value; } void diff --git a/content/base/src/nsNameSpaceManager.cpp b/content/base/src/nsNameSpaceManager.cpp index de71353a4ced..4e681d92d71f 100644 --- a/content/base/src/nsNameSpaceManager.cpp +++ b/content/base/src/nsNameSpaceManager.cpp @@ -57,7 +57,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #endif -using namespace mozilla; using namespace mozilla::dom; #define kXMLNSNameSpaceURI "http://www.w3.org/2000/xmlns/" diff --git a/content/base/src/nsNodeInfoManager.cpp b/content/base/src/nsNodeInfoManager.cpp index 199dc17877b1..20ee96f0ba37 100644 --- a/content/base/src/nsNodeInfoManager.cpp +++ b/content/base/src/nsNodeInfoManager.cpp @@ -56,8 +56,6 @@ #include "nsHashKeys.h" #include "nsCCUncollectableMarker.h" -using namespace mozilla; - #ifdef MOZ_LOGGING // so we can get logging even in release builds #define FORCE_PR_LOG 1 @@ -77,9 +75,6 @@ nsNodeInfoManager::GetNodeInfoInnerHashValue(const void *key) reinterpret_cast(key); if (node->mName) { - // Ideally, we'd return node->mName->hash() here. But that doesn't work at - // the moment because node->mName->hash() is not the same as - // HashString(*(node->mNameString)). See bug 732815. return HashString(nsDependentAtomString(node->mName)); } return HashString(*(node->mNameString)); diff --git a/content/canvas/src/CanvasImageCache.cpp b/content/canvas/src/CanvasImageCache.cpp index ed807f2f16b2..a2189714a8d8 100644 --- a/content/canvas/src/CanvasImageCache.cpp +++ b/content/canvas/src/CanvasImageCache.cpp @@ -102,7 +102,7 @@ public: static KeyTypePointer KeyToPointer(KeyType& key) { return &key; } static PLDHashNumber HashKey(KeyTypePointer key) { - return HashGeneric(key->mImage, key->mCanvas); + return (NS_PTR_TO_INT32(key->mImage) ^ NS_PTR_TO_INT32(key->mCanvas)) >> 2; } enum { ALLOW_MEMMOVE = true }; diff --git a/content/html/content/src/nsHTMLFormElement.h b/content/html/content/src/nsHTMLFormElement.h index e9cdea5cc302..618cf2f12d71 100644 --- a/content/html/content/src/nsHTMLFormElement.h +++ b/content/html/content/src/nsHTMLFormElement.h @@ -49,6 +49,7 @@ #include "nsIURI.h" #include "nsIWeakReferenceUtils.h" #include "nsPIDOMWindow.h" +#include "nsUnicharUtils.h" #include "nsThreadUtils.h" #include "nsInterfaceHashtable.h" #include "nsDataHashtable.h" @@ -56,6 +57,39 @@ class nsFormControlList; class nsIMutableArray; +/** + * hashkey wrapper using nsAString KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr +{ +public: + typedef const nsAString& KeyType; + typedef const nsAString* KeyTypePointer; + nsStringCaseInsensitiveHashKey(KeyTypePointer aStr) : mStr(*aStr) { } //take it easy just deal HashKey + nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey& toCopy) : mStr(toCopy.mStr) { } + ~nsStringCaseInsensitiveHashKey() { } + + KeyType GetKey() const { return mStr; } + bool KeyEquals(const KeyTypePointer aKey) const + { + return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator()); + } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(const KeyTypePointer aKey) + { + nsAutoString tmKey(*aKey); + ToLowerCase(tmKey); + return HashString(tmKey); + } + enum { ALLOW_MEMMOVE = true }; + +private: + const nsString mStr; +}; + class nsHTMLFormElement : public nsGenericHTMLElement, public nsIDOMHTMLFormElement, public nsIWebProgressListener, diff --git a/content/xslt/src/xslt/txKeyFunctionCall.cpp b/content/xslt/src/xslt/txKeyFunctionCall.cpp index b499618211b0..f5f24676473c 100644 --- a/content/xslt/src/xslt/txKeyFunctionCall.cpp +++ b/content/xslt/src/xslt/txKeyFunctionCall.cpp @@ -44,9 +44,6 @@ #include "txKey.h" #include "txXSLTPatterns.h" #include "txNamespaceMap.h" -#include "mozilla/HashFunctions.h" - -using namespace mozilla; /* * txKeyFunctionCall @@ -175,9 +172,10 @@ txKeyValueHashEntry::HashKey(const void* aKey) const txKeyValueHashKey* key = static_cast(aKey); - PLDHashNumber hash = HashString(key->mKeyValue); - return AddToHash(hash, key->mKeyName.mNamespaceID, key->mRootIdentifier, - key->mKeyName.mLocalName.get()); + return key->mKeyName.mNamespaceID ^ + NS_PTR_TO_INT32(key->mKeyName.mLocalName.get()) ^ + key->mRootIdentifier ^ + HashString(key->mKeyValue); } bool @@ -195,9 +193,10 @@ txIndexedKeyHashEntry::HashKey(const void* aKey) { const txIndexedKeyHashKey* key = static_cast(aKey); - return HashGeneric(key->mKeyName.mNamespaceID, - key->mRootIdentifier, - key->mKeyName.mLocalName.get()); + + return key->mKeyName.mNamespaceID ^ + NS_PTR_TO_INT32(key->mKeyName.mLocalName.get()) ^ + key->mRootIdentifier; } /* diff --git a/content/xul/templates/src/nsRDFConInstanceTestNode.h b/content/xul/templates/src/nsRDFConInstanceTestNode.h index e6e2162bffd6..783c20f5e227 100644 --- a/content/xul/templates/src/nsRDFConInstanceTestNode.h +++ b/content/xul/templates/src/nsRDFConInstanceTestNode.h @@ -109,8 +109,9 @@ public: return "nsRDFConInstanceTestNode::Element"; } virtual PLHashNumber Hash() const { - return mozilla::HashGeneric(mContainerTest, mEmptyTest, mContainer.get()); - } + return (PLHashNumber(NS_PTR_TO_INT32(mContainer.get())) >> 4) ^ + PLHashNumber(mContainerTest) ^ + (PLHashNumber(mEmptyTest) << 4); } virtual bool Equals(const MemoryElement& aElement) const { if (aElement.Type() == Type()) { diff --git a/content/xul/templates/src/nsRDFPropertyTestNode.h b/content/xul/templates/src/nsRDFPropertyTestNode.h index 2742c37356c4..d5da994b02f8 100644 --- a/content/xul/templates/src/nsRDFPropertyTestNode.h +++ b/content/xul/templates/src/nsRDFPropertyTestNode.h @@ -124,8 +124,9 @@ public: return "nsRDFPropertyTestNode::Element"; } virtual PLHashNumber Hash() const { - return mozilla::HashGeneric(mSource.get(), mProperty.get(), mTarget.get()); - } + return PLHashNumber(NS_PTR_TO_INT32(mSource.get())) ^ + (PLHashNumber(NS_PTR_TO_INT32(mProperty.get())) >> 4) ^ + (PLHashNumber(NS_PTR_TO_INT32(mTarget.get())) >> 12); } virtual bool Equals(const MemoryElement& aElement) const { if (aElement.Type() == Type()) { diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index c08d4c480f60..d3e1cc66b367 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -60,8 +60,6 @@ #define NS_INTERFACE_PREFIX "nsI" #define NS_DOM_INTERFACE_PREFIX "nsIDOM" -using namespace mozilla; - // Our extended PLDHashEntryHdr class GlobalNameMapEntry : public PLDHashEntryHdr { @@ -76,6 +74,7 @@ static PLDHashNumber GlobalNameHashHashKey(PLDHashTable *table, const void *key) { const nsAString *str = static_cast(key); + return HashString(*str); } diff --git a/dom/indexedDB/OpenDatabaseHelper.cpp b/dom/indexedDB/OpenDatabaseHelper.cpp index 155d5c7ea603..9997169e0907 100644 --- a/dom/indexedDB/OpenDatabaseHelper.cpp +++ b/dom/indexedDB/OpenDatabaseHelper.cpp @@ -51,7 +51,6 @@ #include "IDBFactory.h" #include "IndexedDatabaseManager.h" -using namespace mozilla; USING_INDEXEDDB_NAMESPACE namespace { diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 183046418cae..3cf54dfcce18 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -56,12 +56,10 @@ #include "prmem.h" #include "nsIContent.h" #include "nsIPluginInstanceOwner.h" -#include "mozilla/HashFunctions.h" #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class" using namespace mozilla::plugins::parent; -using namespace mozilla; #include "mozilla/plugins/PluginScriptableObjectParent.h" using mozilla::plugins::PluginScriptableObjectParent; @@ -1024,7 +1022,8 @@ static PLDHashNumber JSObjWrapperHash(PLDHashTable *table, const void *key) { const nsJSObjWrapperKey *e = static_cast(key); - return HashGeneric(e->mJSObj, e->mNpp); + + return (PLDHashNumber)((PRWord)e->mJSObj ^ (PRWord)e->mNpp) >> 2; } static bool diff --git a/embedding/components/commandhandler/src/nsCommandParams.cpp b/embedding/components/commandhandler/src/nsCommandParams.cpp index e3e8af05ff64..446621e12673 100644 --- a/embedding/components/commandhandler/src/nsCommandParams.cpp +++ b/embedding/components/commandhandler/src/nsCommandParams.cpp @@ -41,9 +41,7 @@ #include "nsCRT.h" #include "nsCommandParams.h" -#include "mozilla/HashFunctions.h" -using namespace mozilla; PLDHashTableOps nsCommandParams::sHashOps = { @@ -358,7 +356,7 @@ nsCommandParams::GetOrMakeEntry(const char * name, PRUint8 entryType, HashEntry* PLDHashNumber nsCommandParams::HashKey(PLDHashTable *table, const void *key) { - return HashString((const char *)key); + return nsCRT::HashCode((const char *)key); } bool diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index a642cac2c913..d730594233c4 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -58,7 +58,6 @@ #include "nsIAtom.h" #include "nsISupportsImpl.h" #include "gfxPattern.h" -#include "mozilla/HashFunctions.h" typedef struct _cairo_scaled_font cairo_scaled_font_t; @@ -796,7 +795,7 @@ protected: bool KeyEquals(const KeyTypePointer aKey) const; static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(const KeyTypePointer aKey) { - return mozilla::HashGeneric(aKey->mStyle->Hash(), aKey->mFontEntry); + return NS_PTR_TO_INT32(aKey->mFontEntry) ^ aKey->mStyle->Hash(); } enum { ALLOW_MEMMOVE = true }; diff --git a/intl/unicharutil/util/nsUnicharUtils.cpp b/intl/unicharutil/util/nsUnicharUtils.cpp index 87677cdce2d8..6ee15d2c9074 100644 --- a/intl/unicharutil/util/nsUnicharUtils.cpp +++ b/intl/unicharutil/util/nsUnicharUtils.cpp @@ -47,7 +47,6 @@ #include "nsXPCOMStrings.h" #include "casetable.h" #include "nsUTF8Utils.h" -#include "nsHashKeys.h" #include @@ -541,33 +540,3 @@ CaseInsensitiveUTF8CharsEqual(const char* aLeft, const char* aRight, return leftChar == rightChar; } -namespace mozilla { - -PRUint32 -HashUTF8AsUTF16(const char* aUTF8, PRUint32 aLength, bool* aErr) -{ - PRUint32 hash = 0; - const char* s = aUTF8; - const char* end = aUTF8 + aLength; - - *aErr = false; - - while (s < end) - { - PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&s, end, aErr); - if (*aErr) { - return 0; - } - - if (ucs4 < PLANE1_BASE) { - hash = AddToHash(hash, ucs4); - } - else { - hash = AddToHash(hash, H_SURROGATE(ucs4), L_SURROGATE(ucs4)); - } - } - - return hash; -} - -} // namespace mozilla diff --git a/intl/unicharutil/util/nsUnicharUtils.h b/intl/unicharutil/util/nsUnicharUtils.h index bf4e502a5164..db8c76fac28d 100644 --- a/intl/unicharutil/util/nsUnicharUtils.h +++ b/intl/unicharutil/util/nsUnicharUtils.h @@ -163,19 +163,4 @@ CaseInsensitiveUTF8CharsEqual(const char* aLeft, const char* aRight, const char** aLeftNext, const char** aRightNext, bool* aErr); -namespace mozilla { - -/** - * Hash a UTF8 string as though it were a UTF16 string. - * - * The value returned is the same as if we converted the string to UTF16 and - * then ran HashString() on the result. - * - * The given |length| is in bytes. - */ -PRUint32 -HashUTF8AsUTF16(const char* aUTF8, PRUint32 aLength, bool* aErr); - -} // namespace mozilla - #endif /* nsUnicharUtils_h__ */ diff --git a/js/src/jsatom.h b/js/src/jsatom.h index 52a83085dfb7..4564fbb641a1 100644 --- a/js/src/jsatom.h +++ b/js/src/jsatom.h @@ -51,7 +51,6 @@ #include "gc/Barrier.h" #include "js/HashTable.h" -#include "mozilla/HashFunctions.h" struct JSIdArray { int length; @@ -174,11 +173,9 @@ namespace js { inline uint32_t HashChars(const jschar *chars, size_t length) { - // We could call mozilla::HashString here, but that isn't inlined. - uint32_t h = 0; - for (size_t i = 0; i < length; i++) - h = mozilla::AddToHash(h, chars[i]); + for (; length; chars++, length--) + h = JS_ROTATE_LEFT32(h, 4) ^ *chars; return h; } diff --git a/js/src/jsdhash.cpp b/js/src/jsdhash.cpp index 49086d13bc11..3088d76ab140 100644 --- a/js/src/jsdhash.cpp +++ b/js/src/jsdhash.cpp @@ -48,7 +48,6 @@ #include #include "jsdhash.h" #include "jsutil.h" -#include "mozilla/HashFunctions.h" using namespace js; @@ -126,7 +125,13 @@ JS_DHashFreeTable(JSDHashTable *table, void *ptr) JS_PUBLIC_API(JSDHashNumber) JS_DHashStringKey(JSDHashTable *table, const void *key) { - return mozilla::HashString(static_cast(key)); + JSDHashNumber h; + const unsigned char *s; + + h = 0; + for (s = (const unsigned char *) key; *s != '\0'; s++) + h = JS_ROTATE_LEFT32(h, 4) ^ *s; + return h; } JS_PUBLIC_API(JSDHashNumber) diff --git a/js/src/jshash.cpp b/js/src/jshash.cpp index 17cb600f7e58..c15df4364439 100644 --- a/js/src/jshash.cpp +++ b/js/src/jshash.cpp @@ -45,7 +45,6 @@ #include "jstypes.h" #include "jsutil.h" #include "jshash.h" -#include "mozilla/HashFunctions.h" using namespace js; @@ -462,7 +461,13 @@ JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp) JS_PUBLIC_API(JSHashNumber) JS_HashString(const void *key) { - return mozilla::HashString(static_cast(key)); + JSHashNumber h; + const unsigned char *s; + + h = 0; + for (s = (const unsigned char *)key; *s; s++) + h = JS_ROTATE_LEFT32(h, 4) ^ *s; + return h; } JS_PUBLIC_API(int) diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 3a644560d66a..d344b888d355 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -2527,7 +2527,7 @@ struct types::ArrayTableKey typedef ArrayTableKey Lookup; static inline uint32_t hash(const ArrayTableKey &v) { - return HashGeneric(v.type.raw(), v.proto); + return (uint32_t) (v.type.raw() ^ ((uint32_t)(size_t)v.proto >> 2)); } static inline bool match(const ArrayTableKey &v1, const ArrayTableKey &v2) { @@ -2615,10 +2615,9 @@ struct types::ObjectTableKey typedef JSObject * Lookup; static inline uint32_t hash(JSObject *obj) { - return HashGeneric(JSID_BITS(obj->lastProperty()->propid().get()), - obj->slotSpan(), - obj->numFixedSlots(), - obj->getProto()); + return (uint32_t) (JSID_BITS(obj->lastProperty()->propid().get()) ^ + obj->slotSpan() ^ obj->numFixedSlots() ^ + ((uint32_t)(size_t)obj->getProto() >> 2)); } static inline bool match(const ObjectTableKey &v, JSObject *obj) { diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 476097361f6c..d7923b84aaa0 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -46,7 +46,6 @@ #include "jsinfer.h" #include "jsprf.h" #include "vm/GlobalObject.h" -#include "mozilla/HashFunctions.h" #include "vm/Stack-inl.h" @@ -536,8 +535,7 @@ struct AllocationSiteKey { typedef AllocationSiteKey Lookup; static inline uint32_t hash(AllocationSiteKey key) { - return mozilla::HashGeneric(uint32_t(size_t(key.script->code + key.offset)), - key.kind); + return uint32_t(size_t(key.script->code + key.offset)) ^ key.kind; } static inline bool match(const AllocationSiteKey &a, const AllocationSiteKey &b) { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index bc0dba8d42a1..e47b39ccaeea 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -45,7 +45,6 @@ #include #include "mozilla/Util.h" -#include "mozilla/HashFunctions.h" #include "jstypes.h" #include "jsutil.h" @@ -758,8 +757,9 @@ EvalCacheHash(JSContext *cx, JSLinearString *str) n = 100; uint32_t h; for (h = 0; n; s++, n--) - h = mozilla::AddToHash(h, *s); + h = JS_ROTATE_LEFT32(h, 4) ^ *s; + h *= JS_GOLDEN_RATIO; h >>= 32 - JS_EVAL_CACHE_SHIFT; return &cx->compartment->evalCache[h]; } diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 4736e82a01ef..d09d13384b1b 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -1557,12 +1557,13 @@ class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescri inline bool NewObjectCache::lookup(Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry) { - uintptr_t hash = mozilla::HashGeneric(clasp, key, kind); + uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind; *pentry = hash % js::ArrayLength(entries); Entry *entry = &entries[*pentry]; - return (entry->clasp == clasp && entry->key == key && entry->kind == kind); + /* N.B. Lookups with the same clasp/key but different kinds map to different entries. */ + return (entry->clasp == clasp && entry->key == key); } inline bool diff --git a/js/src/jspropertycache.h b/js/src/jspropertycache.h index c78c2fdbdfd3..89b5023d0639 100644 --- a/js/src/jspropertycache.h +++ b/js/src/jspropertycache.h @@ -44,7 +44,6 @@ #include "jsapi.h" #include "jsprvtd.h" #include "jstypes.h" -#include "mozilla/HashFunctions.h" #include "vm/String.h" @@ -178,7 +177,7 @@ class PropertyCache static inline uintptr_t hash(jsbytecode *pc, const Shape *kshape) { - return mozilla::HashGeneric(pc, kshape) & MASK; + return (((uintptr_t(pc) >> SIZE_LOG2) ^ uintptr_t(pc) ^ ((uintptr_t)kshape >> 3)) & MASK); } static inline bool matchShape(JSContext *cx, JSObject *obj, uint32_t shape); diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index d3a2ba7dafaf..7afca25be9dd 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -1264,9 +1264,12 @@ Shape::setObjectFlag(JSContext *cx, BaseShape::Flag flag, JSObject *proto, Shape /* static */ inline HashNumber StackBaseShape::hash(const StackBaseShape *base) { - JSDHashNumber hash = HashGeneric(base->flags); - return AddToHash(hash, base->clasp, base->parent, - base->rawGetter, base->rawSetter); + JSDHashNumber hash = base->flags; + hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->clasp) >> 3); + hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->parent) >> 3); + hash = JS_ROTATE_LEFT32(hash, 4) ^ uintptr_t(base->rawGetter); + hash = JS_ROTATE_LEFT32(hash, 4) ^ uintptr_t(base->rawSetter); + return hash; } /* static */ inline bool @@ -1398,8 +1401,10 @@ Bindings::setParent(JSContext *cx, JSObject *obj) /* static */ inline HashNumber InitialShapeEntry::hash(const Lookup &lookup) { - JSDHashNumber hash = HashGeneric(lookup.clasp, lookup.proto, lookup.parent); - return AddToHash(hash, lookup.nfixed); + JSDHashNumber hash = uintptr_t(lookup.clasp) >> 3; + hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.proto) >> 3); + hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.parent) >> 3); + return hash + lookup.nfixed; } /* static */ inline bool diff --git a/js/src/jsscopeinlines.h b/js/src/jsscopeinlines.h index 7d01ebecbc0d..75352eaf6eed 100644 --- a/js/src/jsscopeinlines.h +++ b/js/src/jsscopeinlines.h @@ -239,9 +239,15 @@ Shape::Shape(UnownedBaseShape *base, uint32_t nfixed) inline JSDHashNumber StackShape::hash() const { - return AddToHash(HashGeneric(base), - flags & Shape::PUBLIC_FLAGS, attrs, - shortid, slot_, JSID_BITS(propid)); + JSDHashNumber hash = uintptr_t(base); + + /* Accumulate from least to most random so the low bits are most random. */ + hash = JS_ROTATE_LEFT32(hash, 4) ^ (flags & Shape::PUBLIC_FLAGS); + hash = JS_ROTATE_LEFT32(hash, 4) ^ attrs; + hash = JS_ROTATE_LEFT32(hash, 4) ^ shortid; + hash = JS_ROTATE_LEFT32(hash, 4) ^ slot_; + hash = JS_ROTATE_LEFT32(hash, 4) ^ JSID_BITS(propid); + return hash; } inline bool diff --git a/js/src/jswatchpoint.cpp b/js/src/jswatchpoint.cpp index 5f9802f887af..a37a2eb8344d 100644 --- a/js/src/jswatchpoint.cpp +++ b/js/src/jswatchpoint.cpp @@ -41,7 +41,6 @@ #include "jsatom.h" #include "jsgcmark.h" #include "jsobjinlines.h" -#include "mozilla/HashFunctions.h" using namespace js; using namespace js::gc; @@ -49,8 +48,7 @@ using namespace js::gc; inline HashNumber DefaultHasher::hash(const Lookup &key) { - return mozilla::HashGeneric(DefaultHasher::hash(key.object.get()), - HashId(key.id.get())); + return DefaultHasher::hash(key.object.get()) ^ HashId(key.id.get()); } class AutoEntryHolder { diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp index 5a49c6b7782e..9b52f4109315 100644 --- a/js/xpconnect/src/XPCMaps.cpp +++ b/js/xpconnect/src/XPCMaps.cpp @@ -43,9 +43,6 @@ #include "xpcprivate.h" #include "jshash.h" -#include "mozilla/HashFunctions.h" - -using namespace mozilla; /***************************************************************************/ // static shared... @@ -91,7 +88,9 @@ HashNativeKey(JSDHashTable *table, const void *key) if (!Set) { NS_ASSERTION(Addition, "bad key"); - h = AddToHash(h, Addition); + // This would be an XOR like below. + // But "0 ^ x == x". So it does not matter. + h = (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2; } else { XPCNativeInterface** Current = Set->GetInterfaceArray(); PRUint16 count = Set->GetInterfaceCount(); @@ -99,13 +98,13 @@ HashNativeKey(JSDHashTable *table, const void *key) count++; for (PRUint16 i = 0; i < count; i++) { if (i == Position) - h = AddToHash(h, Addition); + h ^= (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2; else - h = AddToHash(h, *(Current++)); + h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2; } } else { for (PRUint16 i = 0; i < count; i++) - h = AddToHash(h, *(Current++)); + h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2; } } @@ -554,8 +553,10 @@ XPCNativeScriptableSharedMap::Entry::Hash(JSDHashTable *table, const void *key) // bitmap since it's very rare that it's different when flags and classname // are the same. - h = HashGeneric(obj->GetFlags()); - return AddToHash(h, HashString(obj->GetJSClass()->name)); + h = (JSDHashNumber) obj->GetFlags(); + for (s = (const unsigned char*) obj->GetJSClass()->name; *s != '\0'; s++) + h = JS_ROTATE_LEFT32(h, 4) ^ *s; + return h; } JSBool diff --git a/mfbt/HashFunctions.cpp b/mfbt/HashFunctions.cpp deleted file mode 100644 index 9045e319f979..000000000000 --- a/mfbt/HashFunctions.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Code. - * - * The Initial Developer of the Original Code is - * The Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Justin Lebar - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* Implementations of hash functions */ - -#include "mozilla/HashFunctions.h" -#include - -namespace mozilla { - -MFBT_API(uint32_t) -HashBytes(const void* bytes, size_t length) -{ - uint32_t hash = 0; - const char* b = reinterpret_cast(bytes); - - /* Walk word by word. */ - size_t i = 0; - for (; i < length - (length % sizeof(size_t)); i += sizeof(size_t)) { - /* Do an explicitly unaligned load of the data. */ - size_t data; - memcpy(&data, b + i, sizeof(size_t)); - - hash = AddToHash(hash, data, sizeof(data)); - } - - /* Get the remaining bytes. */ - for (; i < length; i++) { - hash = AddToHash(hash, b[i]); - } - - return hash; -} - -} /* namespace mozilla */ diff --git a/mfbt/HashFunctions.h b/mfbt/HashFunctions.h index dd09cabae93d..9bc088a20bd8 100644 --- a/mfbt/HashFunctions.h +++ b/mfbt/HashFunctions.h @@ -7,41 +7,6 @@ /* Utilities for hashing */ -/* - * This file exports functions for hashing data down to a 32-bit value, - * including: - * - * - HashString Hash a char* or uint16_t/wchar_t* of known or unknown - * length. - * - * - HashBytes Hash a byte array of known length. - * - * - HashGeneric Hash one or more values. Currently, we support uint32_t, - * types which can be implicitly cast to uint32_t, data - * pointers, and function pointers. - * - * - AddToHash Add one or more values to the given hash. This supports the - * same list of types as HashGeneric. - * - * - * You can chain these functions together to hash complex objects. For example: - * - * class ComplexObject { - * char* str; - * uint32_t uint1, uint2; - * void (*callbackFn)(); - * - * uint32_t Hash() { - * uint32_t hash = HashString(str); - * hash = AddToHash(hash, uint1, uint2); - * return AddToHash(hash, callbackFn); - * } - * }; - * - * If you want to hash an nsAString or nsACString, use the HashString functions - * in nsHashKey.h. - */ - #ifndef mozilla_HashFunctions_h_ #define mozilla_HashFunctions_h_ @@ -64,15 +29,18 @@ RotateLeft32(uint32_t value, uint8_t bits) return (value << bits) | (value >> (32 - bits)); } -namespace detail { - +/** + * Add the given value(s) to the given hashcode and return the new hashcode. + * + * AddToHash(h, x, y) is equivalent to AddToHash(AddToHash(h, x), y). + */ +MOZ_WARN_UNUSED_RESULT inline uint32_t -AddU32ToHash(uint32_t hash, uint32_t value) +AddToHash(uint32_t hash, uint32_t value) { /* - * This is the meat of all our hash routines. This hash function is not - * particularly sophisticated, but it seems to work well for our mostly - * plain-text inputs. Implementation notes follow. + * This is not a sophisticated hash routine, but it seems to work well for our + * mostly plain-text inputs. Implementation notes follow. * * Our use of the golden ratio here is arbitrary; we could pick almost any * number which: @@ -90,7 +58,7 @@ AddU32ToHash(uint32_t hash, uint32_t value) * Otherwise, if |hash| is 0 (as it often is for the beginning of a message), * the expression * - * (GoldenRatioU32 * RotateLeft(hash, 5)) |xor| value + * (GoldenRatioU32 * RotateLeft(hash, 5)) ^ value * * evaluates to |value|. * @@ -102,249 +70,43 @@ AddU32ToHash(uint32_t hash, uint32_t value) * has no duplicate elements. This means that multiplying by |m| does not * cause us to skip any possible hash values. * - * It's also nice if |m| has large-ish order mod 2^32 -- that is, if the - * smallest k such that m^k == 1 (mod 2^32) is large -- so we can safely - * multiply our hash value by |m| a few times without negating the - * multiplicative effect. Our golden ratio constant has order 2^29, which is - * more than enough for our purposes.) + * It's also nice if |m| has larger order mod 2^32 -- that is, if the smallest + * k such that m^k == 1 (mod 2^32) is large -- so we can safely multiply our + * hash value by |m| a few times without negating the multiplicative effect. + * Our golden ratio constant has order 2^29, which is more than enough for our + * purposes.) */ return GoldenRatioU32 * (RotateLeft32(hash, 5) ^ value); } -/** - * AddUintptrToHash takes sizeof(uintptr_t) as a template parameter. - */ -template -inline uint32_t -AddUintptrToHash(uint32_t hash, uintptr_t value); - -template<> -inline uint32_t -AddUintptrToHash<4>(uint32_t hash, uintptr_t value) -{ - return AddU32ToHash(hash, static_cast(value)); -} - -template<> -inline uint32_t -AddUintptrToHash<8>(uint32_t hash, uintptr_t value) -{ - /* - * The static cast to uint64_t below is necessary because this function - * sometimes gets compiled on 32-bit platforms (yes, even though it's a - * template and we never call this particular override in a 32-bit build). If - * we do value >> 32 on a 32-bit machine, we're shifting a 32-bit uintptr_t - * right 32 bits, and the compiler throws an error. - */ - uint32_t v1 = static_cast(value); - uint32_t v2 = static_cast(static_cast(value) >> 32); - return AddU32ToHash(AddU32ToHash(hash, v1), v2); -} - -} /* namespace detail */ - -/** - * AddToHash takes a hash and some values and returns a new hash based on the - * inputs. - * - * Currently, we support hashing uint32_t's, values which we can implicitly - * convert to uint32_t, data pointers, and function pointers. - */ -template MOZ_WARN_UNUSED_RESULT inline uint32_t -AddToHash(uint32_t hash, A a) +AddToHash(uint32_t hash, uint32_t v1, uint32_t v2) { - /* - * Try to convert |A| to uint32_t implicitly. If this works, great. If not, - * we'll error out. - */ - return detail::AddU32ToHash(hash, a); -} - -template -MOZ_WARN_UNUSED_RESULT -inline uint32_t -AddToHash(uint32_t hash, A* a) -{ - /* - * You might think this function should just take a void*. But then we'd only - * catch data pointers and couldn't handle function pointers. - */ - - MOZ_STATIC_ASSERT(sizeof(a) == sizeof(uintptr_t), - "Strange pointer!"); - - return detail::AddUintptrToHash(hash, uintptr_t(a)); -} - -template -MOZ_WARN_UNUSED_RESULT -uint32_t -AddToHash(uint32_t hash, A a, B b) -{ - return AddToHash(AddToHash(hash, a), b); -} - -template -MOZ_WARN_UNUSED_RESULT -uint32_t -AddToHash(uint32_t hash, A a, B b, C c) -{ - return AddToHash(AddToHash(hash, a, b), c); -} - -template -MOZ_WARN_UNUSED_RESULT -uint32_t -AddToHash(uint32_t hash, A a, B b, C c, D d) -{ - return AddToHash(AddToHash(hash, a, b, c), d); -} - -template -MOZ_WARN_UNUSED_RESULT -uint32_t -AddToHash(uint32_t hash, A a, B b, C c, D d, E e) -{ - return AddToHash(AddToHash(hash, a, b, c, d), e); -} - -/** - * The HashGeneric class of functions let you hash one or more values. - * - * If you want to hash together two values x and y, calling HashGeneric(x, y) is - * much better than calling AddToHash(x, y), because AddToHash(x, y) assumes - * that x has already been hashed. - */ -template -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashGeneric(A a) -{ - return AddToHash(0, a); -} - -template -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashGeneric(A a, B b) -{ - return AddToHash(0, a, b); -} - -template -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashGeneric(A a, B b, C c) -{ - return AddToHash(0, a, b, c); -} - -template -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashGeneric(A a, B b, C c, D d) -{ - return AddToHash(0, a, b, c, d); -} - -template -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashGeneric(A a, B b, C c, D d, E e) -{ - return AddToHash(0, a, b, c, d, e); -} - -namespace detail { - -template -uint32_t -HashUntilZero(const T* str) -{ - uint32_t hash = 0; - for (T c; (c = *str); str++) - hash = AddToHash(hash, c); - return hash; -} - -template -uint32_t -HashKnownLength(const T* str, size_t length) -{ - uint32_t hash = 0; - for (size_t i = 0; i < length; i++) - hash = AddToHash(hash, str[i]); - return hash; -} - -} /* namespace detail */ - -/** - * The HashString overloads below do just what you'd expect. - * - * If you have the string's length, you might as well call the overload which - * includes the length. It may be marginally faster. - */ -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashString(const char* str) -{ - return detail::HashUntilZero(str); + return AddToHash(AddToHash(hash, v1), v2); } MOZ_WARN_UNUSED_RESULT inline uint32_t -HashString(const char* str, size_t length) +AddToHash(uint32_t hash, uint32_t v1, uint32_t v2, uint32_t v3) { - return detail::HashKnownLength(str, length); + return AddToHash(AddToHash(hash, v1, v2), v3); } MOZ_WARN_UNUSED_RESULT inline uint32_t -HashString(const uint16_t* str) +AddToHash(uint32_t hash, uint32_t v1, uint32_t v2, uint32_t v3, uint32_t v4) { - return detail::HashUntilZero(str); + return AddToHash(AddToHash(hash, v1, v2, v3), v4); } MOZ_WARN_UNUSED_RESULT inline uint32_t -HashString(const uint16_t* str, size_t length) +AddToHash(uint32_t hash, uint32_t v1, uint32_t v2, uint32_t v3, uint32_t v4, uint32_t v5) { - return detail::HashKnownLength(str, length); + return AddToHash(AddToHash(hash, v1, v2, v3, v4), v5); } -/* - * On Windows, wchar_t (PRUnichar) is not the same as uint16_t, even though it's - * the same width! - */ -#ifdef WIN32 -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashString(const wchar_t* str) -{ - return detail::HashUntilZero(str); -} - -MOZ_WARN_UNUSED_RESULT -inline uint32_t -HashString(const wchar_t* str, size_t length) -{ - return detail::HashKnownLength(str, length); -} -#endif - -/** - * Hash some number of bytes. - * - * This hash walks word-by-word, rather than byte-by-byte, so you won't get the - * same result out of HashBytes as you would out of HashString. - */ -MOZ_WARN_UNUSED_RESULT -extern MFBT_API(uint32_t) -HashBytes(const void* bytes, size_t length); - } /* namespace mozilla */ #endif /* __cplusplus */ #endif /* mozilla_HashFunctions_h_ */ diff --git a/mfbt/sources.mk b/mfbt/sources.mk index b1bc6eb2218b..faa3f4f3ca9e 100644 --- a/mfbt/sources.mk +++ b/mfbt/sources.mk @@ -1,4 +1,3 @@ -CPPSRCS += \ - Assertions.cpp \ - HashFunctions.cpp \ - $(NULL) +CPPSRCS += \ + Assertions.cpp \ + $(NULL) diff --git a/modules/libpref/src/Preferences.cpp b/modules/libpref/src/Preferences.cpp index 7e7b2bf08771..f0cc4f681b10 100644 --- a/modules/libpref/src/Preferences.cpp +++ b/modules/libpref/src/Preferences.cpp @@ -40,7 +40,6 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/Util.h" -#include "mozilla/HashFunctions.h" #include "nsXULAppAPI.h" @@ -107,8 +106,9 @@ public: static PLDHashNumber HashKey(const ValueObserverHashKey *aKey) { - PLDHashNumber hash = HashString(aKey->mPrefName); - return AddToHash(hash, aKey->mCallback); + PRUint32 strHash = nsCRT::HashCode(aKey->mPrefName.BeginReading(), + aKey->mPrefName.Length()); + return PR_ROTATE_LEFT32(strHash, 4) ^ NS_PTR_TO_UINT32(aKey->mCallback); } ValueObserverHashKey(const char *aPref, PrefChangedFunc aCallback) : diff --git a/modules/libpref/src/nsPrefBranch.h b/modules/libpref/src/nsPrefBranch.h index 319a975681c5..da9a234dd794 100644 --- a/modules/libpref/src/nsPrefBranch.h +++ b/modules/libpref/src/nsPrefBranch.h @@ -55,7 +55,6 @@ #include "nsCRT.h" #include "prbit.h" #include "nsTraceRefcnt.h" -#include "mozilla/HashFunctions.h" class nsPrefBranch; @@ -72,8 +71,11 @@ class PrefCallback : public PLDHashEntryHdr { static PLDHashNumber HashKey(const PrefCallback *aKey) { - PRUint32 hash = mozilla::HashString(aKey->mDomain); - return mozilla::AddToHash(hash, aKey->mCanonical); + PRUint32 strHash = nsCRT::HashCode(aKey->mDomain.BeginReading(), + aKey->mDomain.Length()); + + return PR_ROTATE_LEFT32(strHash, 4) ^ + NS_PTR_TO_UINT32(aKey->mCanonical); } diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 9ef6a0c4b735..d8bd8a89524c 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -48,9 +48,8 @@ #include "nsMemory.h" #include "nsCOMPtr.h" #include "prio.h" // for read/write flags, permissions, etc. -#include "nsHashKeys.h" -#include "plstr.h" +#include "nsCRT.h" #include "nsIURI.h" #include "nsIStandardURL.h" #include "nsIURLParser.h" @@ -107,10 +106,11 @@ #include "nsIChannelPolicy.h" #include "nsISocketProviderService.h" #include "nsISocketProvider.h" -#include "nsIRedirectChannelRegistrar.h" #include "nsIMIMEHeaderParam.h" #include "mozilla/Services.h" +#include "nsIRedirectChannelRegistrar.h" + #ifdef MOZILLA_INTERNAL_API inline already_AddRefed @@ -1618,7 +1618,7 @@ NS_SecurityHashURI(nsIURI* aURI) nsCAutoString scheme; PRUint32 schemeHash = 0; if (NS_SUCCEEDED(baseURI->GetScheme(scheme))) - schemeHash = mozilla::HashString(scheme); + schemeHash = nsCRT::HashCode(scheme.get()); // TODO figure out how to hash file:// URIs if (scheme.EqualsLiteral("file")) @@ -1631,16 +1631,17 @@ NS_SecurityHashURI(nsIURI* aURI) nsCAutoString spec; PRUint32 specHash = baseURI->GetSpec(spec); if (NS_SUCCEEDED(specHash)) - specHash = mozilla::HashString(spec); + specHash = nsCRT::HashCode(spec.get()); return specHash; } nsCAutoString host; PRUint32 hostHash = 0; if (NS_SUCCEEDED(baseURI->GetAsciiHost(host))) - hostHash = mozilla::HashString(host); + hostHash = nsCRT::HashCode(host.get()); - return mozilla::AddToHash(schemeHash, hostHash, NS_GetRealPort(baseURI)); + // XOR to combine hash values + return schemeHash ^ hostHash ^ NS_GetRealPort(baseURI); } inline bool diff --git a/netwerk/base/public/nsURIHashKey.h b/netwerk/base/public/nsURIHashKey.h index 0a261f3d461b..4f6f2f01a876 100644 --- a/netwerk/base/public/nsURIHashKey.h +++ b/netwerk/base/public/nsURIHashKey.h @@ -40,8 +40,8 @@ #include "pldhash.h" #include "nsCOMPtr.h" +#include "nsCRT.h" #include "nsIURI.h" -#include "nsHashKeys.h" /** * Hashtable key class to use with nsTHashtable/nsBaseHashtable @@ -72,7 +72,7 @@ public: static PLDHashNumber HashKey(const nsIURI* aKey) { nsCAutoString spec; const_cast(aKey)->GetSpec(spec); - return mozilla::HashString(spec); + return nsCRT::HashCode(spec.get()); } enum { ALLOW_MEMMOVE = true }; diff --git a/netwerk/cache/nsCacheEntry.cpp b/netwerk/cache/nsCacheEntry.cpp index bc5ac2aa6528..3c34f10065e7 100644 --- a/netwerk/cache/nsCacheEntry.cpp +++ b/netwerk/cache/nsCacheEntry.cpp @@ -50,9 +50,8 @@ #include "nsCache.h" #include "nsCacheService.h" #include "nsCacheDevice.h" -#include "nsHashKeys.h" +#include "nsCRT.h" -using namespace mozilla; nsCacheEntry::nsCacheEntry(nsCString * key, bool streamBased, @@ -524,7 +523,7 @@ nsCacheEntryHashTable::VisitEntries( PLDHashEnumerator etor, void *arg) PLDHashNumber nsCacheEntryHashTable::HashKey( PLDHashTable *table, const void *key) { - return HashString(*static_cast(key)); + return PL_DHashStringKey(table,((nsCString *)key)->get()); } bool diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h index 8e9adb3c9a8c..a1fa85072f2e 100644 --- a/netwerk/cookie/nsCookieService.h +++ b/netwerk/cookie/nsCookieService.h @@ -127,7 +127,7 @@ class nsCookieEntry : public PLDHashEntryHdr static PLDHashNumber HashKey(KeyTypePointer aKey) { - return mozilla::HashString(*aKey); + return HashString(*aKey); } enum { ALLOW_MEMMOVE = true }; diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index bae320e82106..68b9375dd004 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -64,7 +64,6 @@ #include "plstr.h" #include "nsURLHelper.h" -#include "mozilla/HashFunctions.h" #include "mozilla/FunctionTimer.h" #include "mozilla/TimeStamp.h" #include "mozilla/Telemetry.h" @@ -279,7 +278,7 @@ static PLDHashNumber HostDB_HashKey(PLDHashTable *table, const void *key) { const nsHostKey *hk = static_cast(key); - return AddToHash(HashString(hk->host), RES_KEY_FLAGS(hk->flags), hk->af); + return PL_DHashStringKey(table, hk->host) ^ RES_KEY_FLAGS(hk->flags) ^ hk->af; } static bool diff --git a/netwerk/protocol/http/nsHttp.cpp b/netwerk/protocol/http/nsHttp.cpp index d7312a2f9e18..7d5722821a43 100644 --- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -40,12 +40,9 @@ #include "nsHttp.h" #include "pldhash.h" #include "mozilla/Mutex.h" -#include "mozilla/HashFunctions.h" #include "nsCRT.h" #include "prbit.h" -using namespace mozilla; - #if defined(PR_LOGGING) PRLogModuleInfo *gHttpLog = nsnull; #endif @@ -101,7 +98,7 @@ StringHash(PLDHashTable *table, const void *key) { PLDHashNumber h = 0; for (const char *s = reinterpret_cast(key); *s; ++s) - h = AddToHash(h, nsCRT::ToLower(*s)); + h = PR_ROTATE_LEFT32(h, 4) ^ nsCRT::ToLower(*s); return h; } diff --git a/parser/htmlparser/src/nsHTMLTags.cpp b/parser/htmlparser/src/nsHTMLTags.cpp index 09c423b4e4a7..85755f0e2616 100644 --- a/parser/htmlparser/src/nsHTMLTags.cpp +++ b/parser/htmlparser/src/nsHTMLTags.cpp @@ -43,7 +43,6 @@ #include "nsString.h" #include "nsStaticAtom.h" #include "nsUnicharUtils.h" -#include "mozilla/HashFunctions.h" using namespace mozilla; @@ -326,7 +325,9 @@ PLHashTable* nsHTMLTags::gTagAtomTable; static PLHashNumber HTMLTagsHashCodeUCPtr(const void *key) { - return HashString(static_cast(key)); + const PRUnichar *str = (const PRUnichar *)key; + + return nsCRT::HashCode(str); } static PRIntn diff --git a/rdf/base/src/nsRDFService.cpp b/rdf/base/src/nsRDFService.cpp index 889c18a65f05..e2662de23165 100644 --- a/rdf/base/src/nsRDFService.cpp +++ b/rdf/base/src/nsRDFService.cpp @@ -89,9 +89,6 @@ #include "nsCRT.h" #include "nsCRTGlue.h" #include "prbit.h" -#include "mozilla/HashFunctions.h" - -using namespace mozilla; //////////////////////////////////////////////////////////////////////// @@ -158,7 +155,7 @@ struct ResourceHashEntry : public PLDHashEntryHdr { static PLDHashNumber HashKey(PLDHashTable *table, const void *key) { - return HashString(static_cast(key)); + return nsCRT::HashCode(static_cast(key)); } static bool @@ -196,7 +193,7 @@ struct LiteralHashEntry : public PLDHashEntryHdr { static PLDHashNumber HashKey(PLDHashTable *table, const void *key) { - return HashString(static_cast(key)); + return nsCRT::HashCode(static_cast(key)); } static bool @@ -392,7 +389,12 @@ struct BlobHashEntry : public PLDHashEntryHdr { { const BlobImpl::Data *data = static_cast(key); - return HashBytes(data->mBytes, data->mLength); + + const PRUint8 *p = data->mBytes, *limit = p + data->mLength; + PLDHashNumber h = 0; + for ( ; p < limit; ++p) + h = PR_ROTATE_LEFT32(h, 4) ^ *p; + return h; } static bool diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index 8589c2e0a2cd..5b2a09431686 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -54,7 +54,6 @@ #include "PSMRunnable.h" #include "nsIConsoleService.h" #include "nsIHttpChannelInternal.h" -#include "nsCRT.h" #include "ssl.h" #include "ocsp.h" diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp index 7c6fb2f37f47..4bc64e072f6a 100644 --- a/toolkit/system/gnome/nsAlertsIconListener.cpp +++ b/toolkit/system/gnome/nsAlertsIconListener.cpp @@ -43,7 +43,6 @@ #include "nsIImageToPixbuf.h" #include "nsIStringBundle.h" #include "nsIObserverService.h" -#include "nsCRT.h" #include diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp index aac89d93b157..99befddcf14f 100644 --- a/xpcom/components/ManifestParser.cpp +++ b/xpcom/components/ManifestParser.cpp @@ -1,688 +1,687 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Firefox - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation . - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Philipp Kewisch - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "mozilla/Util.h" - -#include "ManifestParser.h" - -#include - -#include "nsCRT.h" -#include "prio.h" -#include "prprf.h" -#if defined(XP_WIN) -#include -#elif defined(MOZ_WIDGET_COCOA) -#include -#elif defined(MOZ_WIDGET_GTK2) -#include -#endif - -#ifdef MOZ_WIDGET_ANDROID -#include "AndroidBridge.h" -#endif - -#include "mozilla/Services.h" - -#include "nsConsoleMessage.h" -#include "nsTextFormatter.h" -#include "nsVersionComparator.h" -#include "nsXPCOMCIDInternal.h" - -#include "nsIConsoleService.h" -#include "nsIScriptError.h" -#include "nsIXULAppInfo.h" -#include "nsIXULRuntime.h" - -using namespace mozilla; - -struct ManifestDirective -{ - const char* directive; - int argc; - - // Some directives should only be delivered for NS_COMPONENT_LOCATION - // manifests. - bool componentonly; - - bool ischrome; - - bool allowbootstrap; - - // The platform/contentaccessible flags only apply to content directives. - bool contentflags; - - // Function to handle this directive. This isn't a union because C++ still - // hasn't learned how to initialize unions in a sane way. - void (nsComponentManagerImpl::*mgrfunc) - (nsComponentManagerImpl::ManifestProcessingContext& cx, - int lineno, char *const * argv); - void (nsChromeRegistry::*regfunc) - (nsChromeRegistry::ManifestProcessingContext& cx, - int lineno, char *const *argv, - bool platform, bool contentaccessible); - - bool isContract; -}; -static const ManifestDirective kParsingTable[] = { - { "manifest", 1, false, true, true, false, - &nsComponentManagerImpl::ManifestManifest, NULL }, - { "binary-component", 1, true, false, false, false, - &nsComponentManagerImpl::ManifestBinaryComponent, NULL }, - { "interfaces", 1, true, false, false, false, - &nsComponentManagerImpl::ManifestXPT, NULL }, - { "component", 2, true, false, false, false, - &nsComponentManagerImpl::ManifestComponent, NULL }, - { "contract", 2, true, false, false, false, - &nsComponentManagerImpl::ManifestContract, NULL, true}, - { "category", 3, true, false, false, false, - &nsComponentManagerImpl::ManifestCategory, NULL }, - { "content", 2, true, true, true, true, - NULL, &nsChromeRegistry::ManifestContent }, - { "locale", 3, true, true, true, false, - NULL, &nsChromeRegistry::ManifestLocale }, - { "skin", 3, false, true, true, false, - NULL, &nsChromeRegistry::ManifestSkin }, - { "overlay", 2, true, true, false, false, - NULL, &nsChromeRegistry::ManifestOverlay }, - { "style", 2, false, true, false, false, - NULL, &nsChromeRegistry::ManifestStyle }, - { "override", 2, true, true, true, false, - NULL, &nsChromeRegistry::ManifestOverride }, - { "resource", 2, true, true, false, false, - NULL, &nsChromeRegistry::ManifestResource } -}; - -static const char kWhitespace[] = "\t "; - -static bool IsNewline(char c) -{ - return c == '\n' || c == '\r'; -} - -namespace { -struct AutoPR_smprintf_free -{ - AutoPR_smprintf_free(char* buf) - : mBuf(buf) - { - } - - ~AutoPR_smprintf_free() - { - if (mBuf) - PR_smprintf_free(mBuf); - } - - operator char*() const { - return mBuf; - } - - char* mBuf; -}; - -} // anonymous namespace - -void LogMessage(const char* aMsg, ...) -{ - nsCOMPtr console = - do_GetService(NS_CONSOLESERVICE_CONTRACTID); - if (!console) - return; - - va_list args; - va_start(args, aMsg); - AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args)); - va_end(args); - - nsCOMPtr error = - new nsConsoleMessage(NS_ConvertUTF8toUTF16(formatted).get()); - console->LogMessage(error); -} - -void LogMessageWithContext(FileLocation &aFile, - PRUint32 aLineNumber, const char* aMsg, ...) -{ - va_list args; - va_start(args, aMsg); - AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args)); - va_end(args); - if (!formatted) - return; - - nsCString file; - aFile.GetURIString(file); - - nsCOMPtr error = - do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); - if (!error) { - // This can happen early in component registration. Fall back to a - // generic console message. - LogMessage("Warning: in '%s', line %i: %s", file.get(), - aLineNumber, (char*) formatted); - return; - } - - nsCOMPtr console = - do_GetService(NS_CONSOLESERVICE_CONTRACTID); - if (!console) - return; - - nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(), - NS_ConvertUTF8toUTF16(file).get(), NULL, - aLineNumber, 0, nsIScriptError::warningFlag, - "chrome registration"); - if (NS_FAILED(rv)) - return; - - console->LogMessage(error); -} - -/** - * Check for a modifier flag of the following forms: - * "flag" (same as "true") - * "flag=yes|true|1" - * "flag="no|false|0" - * @param aFlag The flag to compare. - * @param aData The tokenized data to check; this is lowercased - * before being passed in. - * @param aResult If the flag is found, the value is assigned here. - * @return Whether the flag was handled. - */ -static bool -CheckFlag(const nsSubstring& aFlag, const nsSubstring& aData, bool& aResult) -{ - if (!StringBeginsWith(aData, aFlag)) - return false; - - if (aFlag.Length() == aData.Length()) { - // the data is simply "flag", which is the same as "flag=yes" - aResult = true; - return true; - } - - if (aData.CharAt(aFlag.Length()) != '=') { - // the data is "flag2=", which is not anything we care about - return false; - } - - if (aData.Length() == aFlag.Length() + 1) { - aResult = false; - return true; - } - - switch (aData.CharAt(aFlag.Length() + 1)) { - case '1': - case 't': //true - case 'y': //yes - aResult = true; - return true; - - case '0': - case 'f': //false - case 'n': //no - aResult = false; - return true; - } - - return false; -} - -enum TriState { - eUnspecified, - eBad, - eOK -}; - -/** - * Check for a modifier flag of the following form: - * "flag=string" - * "flag!=string" - * @param aFlag The flag to compare. - * @param aData The tokenized data to check; this is lowercased - * before being passed in. - * @param aValue The value that is expected. - * @param aResult If this is "ok" when passed in, this is left alone. - * Otherwise if the flag is found it is set to eBad or eOK. - * @return Whether the flag was handled. - */ -static bool -CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData, - const nsSubstring& aValue, TriState& aResult) -{ - if (aData.Length() < aFlag.Length() + 1) - return false; - - if (!StringBeginsWith(aData, aFlag)) - return false; - - bool comparison = true; - if (aData[aFlag.Length()] != '=') { - if (aData[aFlag.Length()] == '!' && - aData.Length() >= aFlag.Length() + 2 && - aData[aFlag.Length() + 1] == '=') - comparison = false; - else - return false; - } - - if (aResult != eOK) { - nsDependentSubstring testdata = Substring(aData, aFlag.Length() + (comparison ? 1 : 2)); - if (testdata.Equals(aValue)) - aResult = comparison ? eOK : eBad; - else - aResult = comparison ? eBad : eOK; - } - - return true; -} - -/** - * Check for a modifier flag of the following form: - * "flag=version" - * "flag<=version" - * "flag=version" - * "flag>version" - * @param aFlag The flag to compare. - * @param aData The tokenized data to check; this is lowercased - * before being passed in. - * @param aValue The value that is expected. If this is empty then no - * comparison will match. - * @param aResult If this is eOK when passed in, this is left alone. - * Otherwise if the flag is found it is set to eBad or eOK. - * @return Whether the flag was handled. - */ - -#define COMPARE_EQ 1 << 0 -#define COMPARE_LT 1 << 1 -#define COMPARE_GT 1 << 2 - -static bool -CheckVersionFlag(const nsString& aFlag, const nsString& aData, - const nsString& aValue, TriState& aResult) -{ - if (aData.Length() < aFlag.Length() + 2) - return false; - - if (!StringBeginsWith(aData, aFlag)) - return false; - - if (aValue.Length() == 0) { - if (aResult != eOK) - aResult = eBad; - return true; - } - - PRUint32 comparison; - nsAutoString testdata; - - switch (aData[aFlag.Length()]) { - case '=': - comparison = COMPARE_EQ; - testdata = Substring(aData, aFlag.Length() + 1); - break; - - case '<': - if (aData[aFlag.Length() + 1] == '=') { - comparison = COMPARE_EQ | COMPARE_LT; - testdata = Substring(aData, aFlag.Length() + 2); - } - else { - comparison = COMPARE_LT; - testdata = Substring(aData, aFlag.Length() + 1); - } - break; - - case '>': - if (aData[aFlag.Length() + 1] == '=') { - comparison = COMPARE_EQ | COMPARE_GT; - testdata = Substring(aData, aFlag.Length() + 2); - } - else { - comparison = COMPARE_GT; - testdata = Substring(aData, aFlag.Length() + 1); - } - break; - - default: - return false; - } - - if (testdata.Length() == 0) - return false; - - if (aResult != eOK) { - PRInt32 c = NS_CompareVersions(NS_ConvertUTF16toUTF8(aValue).get(), - NS_ConvertUTF16toUTF8(testdata).get()); - if ((c == 0 && comparison & COMPARE_EQ) || - (c < 0 && comparison & COMPARE_LT) || - (c > 0 && comparison & COMPARE_GT)) - aResult = eOK; - else - aResult = eBad; - } - - return true; -} - -// In-place conversion of ascii characters to lower case -static void -ToLowerCase(char* token) -{ - for (; *token; ++token) - *token = NS_ToLower(*token); -} - -namespace { - -struct CachedDirective -{ - int lineno; - char* argv[4]; -}; - -} // anonymous namespace - - -void -ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly) -{ - nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly); - nsChromeRegistry::ManifestProcessingContext chromecx(type, file); - nsresult rv; - - NS_NAMED_LITERAL_STRING(kPlatform, "platform"); - NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible"); - NS_NAMED_LITERAL_STRING(kApplication, "application"); - NS_NAMED_LITERAL_STRING(kAppVersion, "appversion"); - NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion"); - NS_NAMED_LITERAL_STRING(kOs, "os"); - NS_NAMED_LITERAL_STRING(kOsVersion, "osversion"); - NS_NAMED_LITERAL_STRING(kABI, "abi"); -#if defined(MOZ_WIDGET_ANDROID) - NS_NAMED_LITERAL_STRING(kTablet, "tablet"); -#endif - - // Obsolete - NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers"); - - nsAutoString appID; - nsAutoString appVersion; - nsAutoString geckoVersion; - nsAutoString osTarget; - nsAutoString abi; - - nsCOMPtr xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID)); - if (xapp) { - nsCAutoString s; - rv = xapp->GetID(s); - if (NS_SUCCEEDED(rv)) - CopyUTF8toUTF16(s, appID); - - rv = xapp->GetVersion(s); - if (NS_SUCCEEDED(rv)) - CopyUTF8toUTF16(s, appVersion); - - rv = xapp->GetPlatformVersion(s); - if (NS_SUCCEEDED(rv)) - CopyUTF8toUTF16(s, geckoVersion); - - nsCOMPtr xruntime (do_QueryInterface(xapp)); - if (xruntime) { - rv = xruntime->GetOS(s); - if (NS_SUCCEEDED(rv)) { - ToLowerCase(s); - CopyUTF8toUTF16(s, osTarget); - } - - rv = xruntime->GetXPCOMABI(s); - if (NS_SUCCEEDED(rv) && osTarget.Length()) { - ToLowerCase(s); - CopyUTF8toUTF16(s, abi); - abi.Insert(PRUnichar('_'), 0); - abi.Insert(osTarget, 0); - } - } - } - - nsAutoString osVersion; -#if defined(XP_WIN) - OSVERSIONINFO info = { sizeof(OSVERSIONINFO) }; - if (GetVersionEx(&info)) { - nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(), - info.dwMajorVersion, - info.dwMinorVersion); - } -#elif defined(MOZ_WIDGET_COCOA) - SInt32 majorVersion, minorVersion; - if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) && - (Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) { - nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(), - majorVersion, - minorVersion); - } -#elif defined(MOZ_WIDGET_GTK2) - nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(), - gtk_major_version, - gtk_minor_version); -#elif defined(MOZ_WIDGET_ANDROID) - bool isTablet = false; - if (mozilla::AndroidBridge::Bridge()) { - mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", osVersion); - isTablet = mozilla::AndroidBridge::Bridge()->IsTablet(); - } -#endif - - // Because contracts must be registered after CIDs, we save and process them - // at the end. - nsTArray contracts; - - char *token; - char *newline = buf; - PRUint32 line = 0; - - // outer loop tokenizes by newline - while (*newline) { - while (*newline && IsNewline(*newline)) { - ++newline; - ++line; - } - if (!*newline) - break; - - token = newline; - while (*newline && !IsNewline(*newline)) - ++newline; - - if (*newline) { - *newline = '\0'; - ++newline; - } - ++line; - - if (*token == '#') // ignore lines that begin with # as comments - continue; - - char *whitespace = token; - token = nsCRT::strtok(whitespace, kWhitespace, &whitespace); - if (!token) continue; - - const ManifestDirective* directive = NULL; - for (const ManifestDirective* d = kParsingTable; - d < ArrayEnd(kParsingTable); - ++d) { - if (!strcmp(d->directive, token)) { - directive = d; - break; - } - } - - if (!directive) { - LogMessageWithContext(file, line, - "Ignoring unrecognized chrome manifest directive '%s'.", - token); - continue; - } - - if (!directive->allowbootstrap && NS_BOOTSTRAPPED_LOCATION == type) { - LogMessageWithContext(file, line, - "Bootstrapped manifest not allowed to use '%s' directive.", - token); - continue; - } - - if (directive->componentonly && NS_SKIN_LOCATION == type) { - LogMessageWithContext(file, line, - "Skin manifest not allowed to use '%s' directive.", - token); - continue; - } - - NS_ASSERTION(directive->argc < 4, "Need to reset argv array length"); - char* argv[4]; - for (int i = 0; i < directive->argc; ++i) - argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace); - - if (!argv[directive->argc - 1]) { - LogMessageWithContext(file, line, - "Not enough arguments for chrome manifest directive '%s', expected %i.", - token, directive->argc); - continue; - } - - bool ok = true; - TriState stAppVersion = eUnspecified; - TriState stGeckoVersion = eUnspecified; - TriState stApp = eUnspecified; - TriState stOsVersion = eUnspecified; - TriState stOs = eUnspecified; - TriState stABI = eUnspecified; -#if defined(MOZ_WIDGET_ANDROID) - TriState stTablet = eUnspecified; -#endif - bool platform = false; - bool contentAccessible = false; - - while (NULL != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && ok) { - ToLowerCase(token); - NS_ConvertASCIItoUTF16 wtoken(token); - - if (CheckStringFlag(kApplication, wtoken, appID, stApp) || - CheckStringFlag(kOs, wtoken, osTarget, stOs) || - CheckStringFlag(kABI, wtoken, abi, stABI) || - CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || - CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || - CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) - continue; - -#if defined(MOZ_WIDGET_ANDROID) - bool tablet = false; - if (CheckFlag(kTablet, wtoken, tablet)) { - stTablet = (tablet == isTablet) ? eOK : eBad; - continue; - } -#endif - - if (directive->contentflags && - (CheckFlag(kPlatform, wtoken, platform) || - CheckFlag(kContentAccessible, wtoken, contentAccessible))) - continue; - - bool xpcNativeWrappers = true; // Dummy for CheckFlag. - if (CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers)) { - LogMessageWithContext(file, line, - "Ignoring obsolete chrome registration modifier '%s'.", - token); - continue; - } - - LogMessageWithContext(file, line, - "Unrecognized chrome manifest modifier '%s'.", - token); - ok = false; - } - - if (!ok || - stApp == eBad || - stAppVersion == eBad || - stGeckoVersion == eBad || - stOs == eBad || - stOsVersion == eBad || -#ifdef MOZ_WIDGET_ANDROID - stTablet == eBad || -#endif - stABI == eBad) - continue; - - if (directive->regfunc) { - if (GeckoProcessType_Default != XRE_GetProcessType()) - continue; - - if (!nsChromeRegistry::gChromeRegistry) { - nsCOMPtr cr = - mozilla::services::GetChromeRegistryService(); - if (!nsChromeRegistry::gChromeRegistry) { - LogMessageWithContext(file, line, - "Chrome registry isn't available yet."); - continue; - } - } - - (nsChromeRegistry::gChromeRegistry->*(directive->regfunc)) - (chromecx, line, argv, platform, contentAccessible); - } - else if (directive->ischrome || !aChromeOnly) { - if (directive->isContract) { - CachedDirective* cd = contracts.AppendElement(); - cd->lineno = line; - cd->argv[0] = argv[0]; - cd->argv[1] = argv[1]; - } - else - (nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc)) - (mgrcx, line, argv); - } - } - - for (PRUint32 i = 0; i < contracts.Length(); ++i) { - CachedDirective& d = contracts[i]; - nsComponentManagerImpl::gComponentManager->ManifestContract - (mgrcx, d.lineno, d.argv); - } -} +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Firefox + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation . + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Philipp Kewisch + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "mozilla/Util.h" + +#include "ManifestParser.h" + +#include + +#include "prio.h" +#include "prprf.h" +#if defined(XP_WIN) +#include +#elif defined(MOZ_WIDGET_COCOA) +#include +#elif defined(MOZ_WIDGET_GTK2) +#include +#endif + +#ifdef MOZ_WIDGET_ANDROID +#include "AndroidBridge.h" +#endif + +#include "mozilla/Services.h" + +#include "nsConsoleMessage.h" +#include "nsTextFormatter.h" +#include "nsVersionComparator.h" +#include "nsXPCOMCIDInternal.h" + +#include "nsIConsoleService.h" +#include "nsIScriptError.h" +#include "nsIXULAppInfo.h" +#include "nsIXULRuntime.h" + +using namespace mozilla; + +struct ManifestDirective +{ + const char* directive; + int argc; + + // Some directives should only be delivered for NS_COMPONENT_LOCATION + // manifests. + bool componentonly; + + bool ischrome; + + bool allowbootstrap; + + // The platform/contentaccessible flags only apply to content directives. + bool contentflags; + + // Function to handle this directive. This isn't a union because C++ still + // hasn't learned how to initialize unions in a sane way. + void (nsComponentManagerImpl::*mgrfunc) + (nsComponentManagerImpl::ManifestProcessingContext& cx, + int lineno, char *const * argv); + void (nsChromeRegistry::*regfunc) + (nsChromeRegistry::ManifestProcessingContext& cx, + int lineno, char *const *argv, + bool platform, bool contentaccessible); + + bool isContract; +}; +static const ManifestDirective kParsingTable[] = { + { "manifest", 1, false, true, true, false, + &nsComponentManagerImpl::ManifestManifest, NULL }, + { "binary-component", 1, true, false, false, false, + &nsComponentManagerImpl::ManifestBinaryComponent, NULL }, + { "interfaces", 1, true, false, false, false, + &nsComponentManagerImpl::ManifestXPT, NULL }, + { "component", 2, true, false, false, false, + &nsComponentManagerImpl::ManifestComponent, NULL }, + { "contract", 2, true, false, false, false, + &nsComponentManagerImpl::ManifestContract, NULL, true}, + { "category", 3, true, false, false, false, + &nsComponentManagerImpl::ManifestCategory, NULL }, + { "content", 2, true, true, true, true, + NULL, &nsChromeRegistry::ManifestContent }, + { "locale", 3, true, true, true, false, + NULL, &nsChromeRegistry::ManifestLocale }, + { "skin", 3, false, true, true, false, + NULL, &nsChromeRegistry::ManifestSkin }, + { "overlay", 2, true, true, false, false, + NULL, &nsChromeRegistry::ManifestOverlay }, + { "style", 2, false, true, false, false, + NULL, &nsChromeRegistry::ManifestStyle }, + { "override", 2, true, true, true, false, + NULL, &nsChromeRegistry::ManifestOverride }, + { "resource", 2, true, true, false, false, + NULL, &nsChromeRegistry::ManifestResource } +}; + +static const char kWhitespace[] = "\t "; + +static bool IsNewline(char c) +{ + return c == '\n' || c == '\r'; +} + +namespace { +struct AutoPR_smprintf_free +{ + AutoPR_smprintf_free(char* buf) + : mBuf(buf) + { + } + + ~AutoPR_smprintf_free() + { + if (mBuf) + PR_smprintf_free(mBuf); + } + + operator char*() const { + return mBuf; + } + + char* mBuf; +}; + +} // anonymous namespace + +void LogMessage(const char* aMsg, ...) +{ + nsCOMPtr console = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (!console) + return; + + va_list args; + va_start(args, aMsg); + AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args)); + va_end(args); + + nsCOMPtr error = + new nsConsoleMessage(NS_ConvertUTF8toUTF16(formatted).get()); + console->LogMessage(error); +} + +void LogMessageWithContext(FileLocation &aFile, + PRUint32 aLineNumber, const char* aMsg, ...) +{ + va_list args; + va_start(args, aMsg); + AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args)); + va_end(args); + if (!formatted) + return; + + nsCString file; + aFile.GetURIString(file); + + nsCOMPtr error = + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); + if (!error) { + // This can happen early in component registration. Fall back to a + // generic console message. + LogMessage("Warning: in '%s', line %i: %s", file.get(), + aLineNumber, (char*) formatted); + return; + } + + nsCOMPtr console = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (!console) + return; + + nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(), + NS_ConvertUTF8toUTF16(file).get(), NULL, + aLineNumber, 0, nsIScriptError::warningFlag, + "chrome registration"); + if (NS_FAILED(rv)) + return; + + console->LogMessage(error); +} + +/** + * Check for a modifier flag of the following forms: + * "flag" (same as "true") + * "flag=yes|true|1" + * "flag="no|false|0" + * @param aFlag The flag to compare. + * @param aData The tokenized data to check; this is lowercased + * before being passed in. + * @param aResult If the flag is found, the value is assigned here. + * @return Whether the flag was handled. + */ +static bool +CheckFlag(const nsSubstring& aFlag, const nsSubstring& aData, bool& aResult) +{ + if (!StringBeginsWith(aData, aFlag)) + return false; + + if (aFlag.Length() == aData.Length()) { + // the data is simply "flag", which is the same as "flag=yes" + aResult = true; + return true; + } + + if (aData.CharAt(aFlag.Length()) != '=') { + // the data is "flag2=", which is not anything we care about + return false; + } + + if (aData.Length() == aFlag.Length() + 1) { + aResult = false; + return true; + } + + switch (aData.CharAt(aFlag.Length() + 1)) { + case '1': + case 't': //true + case 'y': //yes + aResult = true; + return true; + + case '0': + case 'f': //false + case 'n': //no + aResult = false; + return true; + } + + return false; +} + +enum TriState { + eUnspecified, + eBad, + eOK +}; + +/** + * Check for a modifier flag of the following form: + * "flag=string" + * "flag!=string" + * @param aFlag The flag to compare. + * @param aData The tokenized data to check; this is lowercased + * before being passed in. + * @param aValue The value that is expected. + * @param aResult If this is "ok" when passed in, this is left alone. + * Otherwise if the flag is found it is set to eBad or eOK. + * @return Whether the flag was handled. + */ +static bool +CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData, + const nsSubstring& aValue, TriState& aResult) +{ + if (aData.Length() < aFlag.Length() + 1) + return false; + + if (!StringBeginsWith(aData, aFlag)) + return false; + + bool comparison = true; + if (aData[aFlag.Length()] != '=') { + if (aData[aFlag.Length()] == '!' && + aData.Length() >= aFlag.Length() + 2 && + aData[aFlag.Length() + 1] == '=') + comparison = false; + else + return false; + } + + if (aResult != eOK) { + nsDependentSubstring testdata = Substring(aData, aFlag.Length() + (comparison ? 1 : 2)); + if (testdata.Equals(aValue)) + aResult = comparison ? eOK : eBad; + else + aResult = comparison ? eBad : eOK; + } + + return true; +} + +/** + * Check for a modifier flag of the following form: + * "flag=version" + * "flag<=version" + * "flag=version" + * "flag>version" + * @param aFlag The flag to compare. + * @param aData The tokenized data to check; this is lowercased + * before being passed in. + * @param aValue The value that is expected. If this is empty then no + * comparison will match. + * @param aResult If this is eOK when passed in, this is left alone. + * Otherwise if the flag is found it is set to eBad or eOK. + * @return Whether the flag was handled. + */ + +#define COMPARE_EQ 1 << 0 +#define COMPARE_LT 1 << 1 +#define COMPARE_GT 1 << 2 + +static bool +CheckVersionFlag(const nsString& aFlag, const nsString& aData, + const nsString& aValue, TriState& aResult) +{ + if (aData.Length() < aFlag.Length() + 2) + return false; + + if (!StringBeginsWith(aData, aFlag)) + return false; + + if (aValue.Length() == 0) { + if (aResult != eOK) + aResult = eBad; + return true; + } + + PRUint32 comparison; + nsAutoString testdata; + + switch (aData[aFlag.Length()]) { + case '=': + comparison = COMPARE_EQ; + testdata = Substring(aData, aFlag.Length() + 1); + break; + + case '<': + if (aData[aFlag.Length() + 1] == '=') { + comparison = COMPARE_EQ | COMPARE_LT; + testdata = Substring(aData, aFlag.Length() + 2); + } + else { + comparison = COMPARE_LT; + testdata = Substring(aData, aFlag.Length() + 1); + } + break; + + case '>': + if (aData[aFlag.Length() + 1] == '=') { + comparison = COMPARE_EQ | COMPARE_GT; + testdata = Substring(aData, aFlag.Length() + 2); + } + else { + comparison = COMPARE_GT; + testdata = Substring(aData, aFlag.Length() + 1); + } + break; + + default: + return false; + } + + if (testdata.Length() == 0) + return false; + + if (aResult != eOK) { + PRInt32 c = NS_CompareVersions(NS_ConvertUTF16toUTF8(aValue).get(), + NS_ConvertUTF16toUTF8(testdata).get()); + if ((c == 0 && comparison & COMPARE_EQ) || + (c < 0 && comparison & COMPARE_LT) || + (c > 0 && comparison & COMPARE_GT)) + aResult = eOK; + else + aResult = eBad; + } + + return true; +} + +// In-place conversion of ascii characters to lower case +static void +ToLowerCase(char* token) +{ + for (; *token; ++token) + *token = NS_ToLower(*token); +} + +namespace { + +struct CachedDirective +{ + int lineno; + char* argv[4]; +}; + +} // anonymous namespace + + +void +ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly) +{ + nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly); + nsChromeRegistry::ManifestProcessingContext chromecx(type, file); + nsresult rv; + + NS_NAMED_LITERAL_STRING(kPlatform, "platform"); + NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible"); + NS_NAMED_LITERAL_STRING(kApplication, "application"); + NS_NAMED_LITERAL_STRING(kAppVersion, "appversion"); + NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion"); + NS_NAMED_LITERAL_STRING(kOs, "os"); + NS_NAMED_LITERAL_STRING(kOsVersion, "osversion"); + NS_NAMED_LITERAL_STRING(kABI, "abi"); +#if defined(MOZ_WIDGET_ANDROID) + NS_NAMED_LITERAL_STRING(kTablet, "tablet"); +#endif + + // Obsolete + NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers"); + + nsAutoString appID; + nsAutoString appVersion; + nsAutoString geckoVersion; + nsAutoString osTarget; + nsAutoString abi; + + nsCOMPtr xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID)); + if (xapp) { + nsCAutoString s; + rv = xapp->GetID(s); + if (NS_SUCCEEDED(rv)) + CopyUTF8toUTF16(s, appID); + + rv = xapp->GetVersion(s); + if (NS_SUCCEEDED(rv)) + CopyUTF8toUTF16(s, appVersion); + + rv = xapp->GetPlatformVersion(s); + if (NS_SUCCEEDED(rv)) + CopyUTF8toUTF16(s, geckoVersion); + + nsCOMPtr xruntime (do_QueryInterface(xapp)); + if (xruntime) { + rv = xruntime->GetOS(s); + if (NS_SUCCEEDED(rv)) { + ToLowerCase(s); + CopyUTF8toUTF16(s, osTarget); + } + + rv = xruntime->GetXPCOMABI(s); + if (NS_SUCCEEDED(rv) && osTarget.Length()) { + ToLowerCase(s); + CopyUTF8toUTF16(s, abi); + abi.Insert(PRUnichar('_'), 0); + abi.Insert(osTarget, 0); + } + } + } + + nsAutoString osVersion; +#if defined(XP_WIN) + OSVERSIONINFO info = { sizeof(OSVERSIONINFO) }; + if (GetVersionEx(&info)) { + nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(), + info.dwMajorVersion, + info.dwMinorVersion); + } +#elif defined(MOZ_WIDGET_COCOA) + SInt32 majorVersion, minorVersion; + if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) && + (Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) { + nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(), + majorVersion, + minorVersion); + } +#elif defined(MOZ_WIDGET_GTK2) + nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(), + gtk_major_version, + gtk_minor_version); +#elif defined(MOZ_WIDGET_ANDROID) + bool isTablet = false; + if (mozilla::AndroidBridge::Bridge()) { + mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", osVersion); + isTablet = mozilla::AndroidBridge::Bridge()->IsTablet(); + } +#endif + + // Because contracts must be registered after CIDs, we save and process them + // at the end. + nsTArray contracts; + + char *token; + char *newline = buf; + PRUint32 line = 0; + + // outer loop tokenizes by newline + while (*newline) { + while (*newline && IsNewline(*newline)) { + ++newline; + ++line; + } + if (!*newline) + break; + + token = newline; + while (*newline && !IsNewline(*newline)) + ++newline; + + if (*newline) { + *newline = '\0'; + ++newline; + } + ++line; + + if (*token == '#') // ignore lines that begin with # as comments + continue; + + char *whitespace = token; + token = nsCRT::strtok(whitespace, kWhitespace, &whitespace); + if (!token) continue; + + const ManifestDirective* directive = NULL; + for (const ManifestDirective* d = kParsingTable; + d < ArrayEnd(kParsingTable); + ++d) { + if (!strcmp(d->directive, token)) { + directive = d; + break; + } + } + + if (!directive) { + LogMessageWithContext(file, line, + "Ignoring unrecognized chrome manifest directive '%s'.", + token); + continue; + } + + if (!directive->allowbootstrap && NS_BOOTSTRAPPED_LOCATION == type) { + LogMessageWithContext(file, line, + "Bootstrapped manifest not allowed to use '%s' directive.", + token); + continue; + } + + if (directive->componentonly && NS_SKIN_LOCATION == type) { + LogMessageWithContext(file, line, + "Skin manifest not allowed to use '%s' directive.", + token); + continue; + } + + NS_ASSERTION(directive->argc < 4, "Need to reset argv array length"); + char* argv[4]; + for (int i = 0; i < directive->argc; ++i) + argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace); + + if (!argv[directive->argc - 1]) { + LogMessageWithContext(file, line, + "Not enough arguments for chrome manifest directive '%s', expected %i.", + token, directive->argc); + continue; + } + + bool ok = true; + TriState stAppVersion = eUnspecified; + TriState stGeckoVersion = eUnspecified; + TriState stApp = eUnspecified; + TriState stOsVersion = eUnspecified; + TriState stOs = eUnspecified; + TriState stABI = eUnspecified; +#if defined(MOZ_WIDGET_ANDROID) + TriState stTablet = eUnspecified; +#endif + bool platform = false; + bool contentAccessible = false; + + while (NULL != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && ok) { + ToLowerCase(token); + NS_ConvertASCIItoUTF16 wtoken(token); + + if (CheckStringFlag(kApplication, wtoken, appID, stApp) || + CheckStringFlag(kOs, wtoken, osTarget, stOs) || + CheckStringFlag(kABI, wtoken, abi, stABI) || + CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || + CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || + CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) + continue; + +#if defined(MOZ_WIDGET_ANDROID) + bool tablet = false; + if (CheckFlag(kTablet, wtoken, tablet)) { + stTablet = (tablet == isTablet) ? eOK : eBad; + continue; + } +#endif + + if (directive->contentflags && + (CheckFlag(kPlatform, wtoken, platform) || + CheckFlag(kContentAccessible, wtoken, contentAccessible))) + continue; + + bool xpcNativeWrappers = true; // Dummy for CheckFlag. + if (CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers)) { + LogMessageWithContext(file, line, + "Ignoring obsolete chrome registration modifier '%s'.", + token); + continue; + } + + LogMessageWithContext(file, line, + "Unrecognized chrome manifest modifier '%s'.", + token); + ok = false; + } + + if (!ok || + stApp == eBad || + stAppVersion == eBad || + stGeckoVersion == eBad || + stOs == eBad || + stOsVersion == eBad || +#ifdef MOZ_WIDGET_ANDROID + stTablet == eBad || +#endif + stABI == eBad) + continue; + + if (directive->regfunc) { + if (GeckoProcessType_Default != XRE_GetProcessType()) + continue; + + if (!nsChromeRegistry::gChromeRegistry) { + nsCOMPtr cr = + mozilla::services::GetChromeRegistryService(); + if (!nsChromeRegistry::gChromeRegistry) { + LogMessageWithContext(file, line, + "Chrome registry isn't available yet."); + continue; + } + } + + (nsChromeRegistry::gChromeRegistry->*(directive->regfunc)) + (chromecx, line, argv, platform, contentAccessible); + } + else if (directive->ischrome || !aChromeOnly) { + if (directive->isContract) { + CachedDirective* cd = contracts.AppendElement(); + cd->lineno = line; + cd->argv[0] = argv[0]; + cd->argv[1] = argv[1]; + } + else + (nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc)) + (mgrcx, line, argv); + } + } + + for (PRUint32 i = 0; i < contracts.Length(); ++i) { + CachedDirective& d = contracts[i]; + nsComponentManagerImpl::gComponentManager->ManifestContract + (mgrcx, d.lineno, d.argv); + } +} diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 586c4957ba87..f60900bb28c4 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -37,7 +37,6 @@ * ***** END LICENSE BLOCK ***** */ #include "mozilla/Assertions.h" -#include "mozilla/HashFunctions.h" #include "nsAtomTable.h" #include "nsStaticAtom.h" @@ -51,13 +50,10 @@ #include "nsDataHashtable.h" #include "nsHashKeys.h" #include "nsAutoPtr.h" -#include "nsUnicharUtils.h" #define PL_ARENA_CONST_ALIGN_MASK 3 #include "plarena.h" -using namespace mozilla; - /** * The shared hash table for atom lookups. * @@ -196,7 +192,7 @@ AtomTableGetHash(PLDHashTable *table, const void *key) if (k->mUTF8String) { bool err; - PRUint32 hash = HashUTF8AsUTF16(k->mUTF8String, k->mLength, &err); + PRUint32 hash = nsCRT::HashCodeAsUTF16(k->mUTF8String, k->mLength, &err); if (err) { AtomTableKey* mutableKey = const_cast(k); mutableKey->mUTF8String = nsnull; @@ -206,7 +202,7 @@ AtomTableGetHash(PLDHashTable *table, const void *key) return hash; } - return HashString(k->mUTF16String, k->mLength); + return nsCRT::HashCode(k->mUTF16String, k->mLength); } static bool diff --git a/xpcom/ds/nsCRT.cpp b/xpcom/ds/nsCRT.cpp index e60f1c0955fe..9de1ea93d946 100644 --- a/xpcom/ds/nsCRT.cpp +++ b/xpcom/ds/nsCRT.cpp @@ -55,6 +55,9 @@ #include "nsIServiceManager.h" #include "nsCharTraits.h" #include "nsUTF8Utils.h" +#include "mozilla/HashFunctions.h" + +using namespace mozilla; //---------------------------------------------------------------------- @@ -199,6 +202,108 @@ PRUnichar* nsCRT::strndup(const PRUnichar* str, PRUint32 len) return rslt; } + /** + * |nsCRT::HashCode| is identical to |PL_HashString|, which tests + * (http://bugzilla.mozilla.org/showattachment.cgi?attach_id=26596) + * show to be the best hash among several other choices. + * + * We re-implement it here rather than calling it for two reasons: + * (1) in this interface, we also calculate the length of the + * string being hashed; and (2) the narrow and wide and `buffer' versions here + * will hash equivalent strings to the same value, e.g., "Hello" and L"Hello". + */ +PRUint32 nsCRT::HashCode(const char* str, PRUint32* resultingStrLen) +{ + PRUint32 h = 0; + const char* s = str; + + if (!str) return h; + + unsigned char c; + while ( (c = *s++) ) { + h = AddToHash(h, c); + } + + if ( resultingStrLen ) + *resultingStrLen = (s-str)-1; + + return h; +} + +PRUint32 nsCRT::HashCode(const char* start, PRUint32 length) +{ + PRUint32 h = 0; + const char* s = start; + const char* end = start + length; + + unsigned char c; + while ( s < end ) { + c = *s++; + h = AddToHash(h, c); + } + + return h; +} + +PRUint32 nsCRT::HashCode(const PRUnichar* str, PRUint32* resultingStrLen) +{ + PRUint32 h = 0; + const PRUnichar* s = str; + + if (!str) return h; + + PRUnichar c; + while ( (c = *s++) ) + h = AddToHash(h, c); + + if ( resultingStrLen ) + *resultingStrLen = (s-str)-1; + + return h; +} + +PRUint32 nsCRT::HashCode(const PRUnichar* start, PRUint32 length) +{ + PRUint32 h = 0; + const PRUnichar* s = start; + const PRUnichar* end = start + length; + + PRUnichar c; + while ( s < end ) { + c = *s++; + h = AddToHash(h, c); + } + + return h; +} + +PRUint32 nsCRT::HashCodeAsUTF16(const char* start, PRUint32 length, + bool* err) +{ + PRUint32 h = 0; + const char* s = start; + const char* end = start + length; + + *err = false; + + while ( s < end ) + { + PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&s, end, err); + if (*err) { + return 0; + } + + if (ucs4 < PLANE1_BASE) { + h = AddToHash(h, ucs4); + } + else { + h = AddToHash(h, H_SURROGATE(ucs4), L_SURROGATE(ucs4)); + } + } + + return h; +} + // This should use NSPR but NSPR isn't exporting its PR_strtoll function // Until then... PRInt64 nsCRT::atoll(const char *str) diff --git a/xpcom/ds/nsCRT.h b/xpcom/ds/nsCRT.h index 34b5bdfca333..8374b5033171 100644 --- a/xpcom/ds/nsCRT.h +++ b/xpcom/ds/nsCRT.h @@ -229,6 +229,28 @@ public: shared_allocator.deallocate(str, 0 /*we never new or kept the size*/); } + // Computes the hashcode for a c-string, returns the string length as + // an added bonus. + static PRUint32 HashCode(const char* str, + PRUint32* resultingStrLen = nsnull); + + // Computes the hashcode for a length number of bytes of c-string data. + static PRUint32 HashCode(const char* start, PRUint32 length); + + // Computes the hashcode for a ucs2 string, returns the string length + // as an added bonus. + static PRUint32 HashCode(const PRUnichar* str, + PRUint32* resultingStrLen = nsnull); + + // Computes the hashcode for a buffer with a specified length. + static PRUint32 HashCode(const PRUnichar* str, PRUint32 strLen); + + // Computes a hashcode for a length number of UTF8 + // characters. Returns the same hash code as the HashCode method + // taking a |PRUnichar*| would if the string were converted to UTF16. + static PRUint32 HashCodeAsUTF16(const char* start, PRUint32 length, + bool* err); + // String to longlong static PRInt64 atoll(const char *str); diff --git a/xpcom/ds/nsDoubleHashtable.h b/xpcom/ds/nsDoubleHashtable.h index c1addf7271e8..72ecdf8eda65 100644 --- a/xpcom/ds/nsDoubleHashtable.h +++ b/xpcom/ds/nsDoubleHashtable.h @@ -406,7 +406,7 @@ public: ~PLDHashStringEntry() { } static PLDHashNumber HashKey(const void* key) { - return mozilla::HashString(*static_cast(key)); + return HashString(*static_cast(key)); } bool MatchEntry(const void* key) const { return static_cast(key)->Equals(mKey); @@ -426,7 +426,7 @@ public: ~PLDHashCStringEntry() { } static PLDHashNumber HashKey(const void* key) { - return mozilla::HashString(*static_cast(key)); + return HashString(*static_cast(key)); } bool MatchEntry(const void* key) const { return static_cast(key)->Equals(mKey); diff --git a/xpcom/ds/nsHashtable.cpp b/xpcom/ds/nsHashtable.cpp index c7c603e1e3b7..7f608f80610d 100644 --- a/xpcom/ds/nsHashtable.cpp +++ b/xpcom/ds/nsHashtable.cpp @@ -54,9 +54,6 @@ #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" #include "nsCRT.h" -#include "mozilla/HashFunctions.h" - -using namespace mozilla; struct HTEntry : PLDHashEntryHdr { @@ -537,7 +534,7 @@ nsCStringKey::~nsCStringKey(void) PRUint32 nsCStringKey::HashCode(void) const { - return HashString(mStr, mStrLen); + return nsCRT::HashCode(mStr, (PRUint32*)&mStrLen); } bool @@ -664,7 +661,7 @@ nsStringKey::~nsStringKey(void) PRUint32 nsStringKey::HashCode(void) const { - return HashString(mStr, mStrLen); + return nsCRT::HashCode(mStr, (PRUint32*)&mStrLen); } bool diff --git a/xpcom/ds/nsStaticNameTable.cpp b/xpcom/ds/nsStaticNameTable.cpp index fdc6b9d0ce8e..294bdf7b0e12 100644 --- a/xpcom/ds/nsStaticNameTable.cpp +++ b/xpcom/ds/nsStaticNameTable.cpp @@ -45,13 +45,10 @@ #include "nsString.h" #include "nsReadableUtils.h" #include "prbit.h" -#include "mozilla/HashFunctions.h" #define PL_ARENA_CONST_ALIGN_MASK 3 #include "nsStaticNameTable.h" -using namespace mozilla; - struct NameTableKey { NameTableKey(const nsAFlatCString* aKeyStr) @@ -116,14 +113,14 @@ caseInsensitiveStringHashKey(PLDHashTable *table, const void *key) for (const PRUnichar* s = tableKey->mKeyStr.m2b->get(); *s != '\0'; s++) - h = AddToHash(h, *s & ~0x20); + h = PR_ROTATE_LEFT32(h, 4) ^ (*s & ~0x20); } else { for (const unsigned char* s = reinterpret_cast (tableKey->mKeyStr.m1b->get()); *s != '\0'; s++) - h = AddToHash(h, *s & ~0x20); + h = PR_ROTATE_LEFT32(h, 4) ^ (*s & ~0x20); } return h; } diff --git a/xpcom/glue/nsHashKeys.h b/xpcom/glue/nsHashKeys.h index af5b6ed512d1..a0bab241183a 100644 --- a/xpcom/glue/nsHashKeys.h +++ b/xpcom/glue/nsHashKeys.h @@ -47,31 +47,10 @@ #include "nsStringGlue.h" #include "nsCRTGlue.h" -#include "nsUnicharUtils.h" #include #include -#include "mozilla/HashFunctions.h" - -namespace mozilla { - -// These are defined analogously to the HashString overloads in mfbt. - -inline PRUint32 -HashString(const nsAString& aStr) -{ - return HashString(aStr.BeginReading(), aStr.Length()); -} - -inline PRUint32 -HashString(const nsACString& aStr) -{ - return HashString(aStr.BeginReading(), aStr.Length()); -} - -} // namespace mozilla - /** @file nsHashKeys.h * standard HashKey classes for nsBaseHashtable and relatives. Each of these * classes follows the nsTHashtable::EntryType specification @@ -93,6 +72,11 @@ HashString(const nsACString& aStr) * nsHashableHashKey */ +NS_COM_GLUE PRUint32 HashString(const nsAString& aStr); +NS_COM_GLUE PRUint32 HashString(const nsACString& aStr); +NS_COM_GLUE PRUint32 HashString(const char* aKey); +NS_COM_GLUE PRUint32 HashString(const PRUnichar* aKey); + /** * hashkey wrapper using nsAString KeyType * @@ -117,7 +101,7 @@ public: static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(const KeyTypePointer aKey) { - return mozilla::HashString(*aKey); + return HashString(*aKey); } enum { ALLOW_MEMMOVE = true }; @@ -125,47 +109,6 @@ private: const nsString mStr; }; -#ifdef MOZILLA_INTERNAL_API - -/** - * hashkey wrapper using nsAString KeyType - * - * This is internal-API only because nsCaseInsensitiveStringComparator is - * internal-only. - * - * @see nsTHashtable::EntryType for specification - */ -class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr -{ -public: - typedef const nsAString& KeyType; - typedef const nsAString* KeyTypePointer; - - nsStringCaseInsensitiveHashKey(KeyTypePointer aStr) : mStr(*aStr) { } //take it easy just deal HashKey - nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey& toCopy) : mStr(toCopy.mStr) { } - ~nsStringCaseInsensitiveHashKey() { } - - KeyType GetKey() const { return mStr; } - bool KeyEquals(const KeyTypePointer aKey) const - { - return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator()); - } - - static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } - static PLDHashNumber HashKey(const KeyTypePointer aKey) - { - nsAutoString tmKey(*aKey); - ToLowerCase(tmKey); - return mozilla::HashString(tmKey); - } - enum { ALLOW_MEMMOVE = true }; - -private: - const nsString mStr; -}; - -#endif - /** * hashkey wrapper using nsACString KeyType * @@ -188,7 +131,7 @@ public: static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { - return mozilla::HashString(*aKey); + return HashString(*aKey); } enum { ALLOW_MEMMOVE = true }; @@ -385,12 +328,7 @@ public: bool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); } static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } - static PLDHashNumber HashKey(KeyTypePointer aKey) - { - // Hash the nsID object's raw bytes. - return mozilla::HashBytes(aKey, sizeof(KeyType)); - } - + static PLDHashNumber HashKey(KeyTypePointer aKey); enum { ALLOW_MEMMOVE = true }; private: @@ -424,7 +362,7 @@ public: } static const char* KeyToPointer(const char* aKey) { return aKey; } - static PLDHashNumber HashKey(const char* aKey) { return mozilla::HashString(aKey); } + static PLDHashNumber HashKey(const char* aKey) { return HashString(aKey); } enum { ALLOW_MEMMOVE = true }; private: @@ -453,7 +391,7 @@ public: } static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } - static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); } + static PLDHashNumber HashKey(KeyTypePointer aKey) { return HashString(aKey); } enum { ALLOW_MEMMOVE = true }; @@ -483,7 +421,7 @@ public: } static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } - static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); } + static PLDHashNumber HashKey(KeyTypePointer aKey) { return HashString(aKey); } enum { ALLOW_MEMMOVE = true }; diff --git a/xpcom/glue/nsTHashtable.cpp b/xpcom/glue/nsTHashtable.cpp index 0dd1f56bd319..f762d8e70970 100644 --- a/xpcom/glue/nsTHashtable.cpp +++ b/xpcom/glue/nsTHashtable.cpp @@ -36,6 +36,85 @@ * ***** END LICENSE BLOCK ***** */ #include "nsTHashtable.h" +#include "nsHashKeys.h" +#include "prbit.h" +#include "mozilla/HashFunctions.h" + +using namespace mozilla; + +PRUint32 +HashString( const nsAString& aStr ) +{ + PRUint32 code = 0; + +#ifdef MOZILLA_INTERNAL_API + nsAString::const_iterator begin, end; + aStr.BeginReading(begin); + aStr.EndReading(end); +#else + const PRUnichar *begin, *end; + PRUint32 len = NS_StringGetData(aStr, &begin); + end = begin + len; +#endif + + while (begin != end) { + code = AddToHash(code, *begin); + ++begin; + } + + return code; +} + +PRUint32 +HashString( const nsACString& aStr ) +{ + PRUint32 code = 0; + +#ifdef MOZILLA_INTERNAL_API + nsACString::const_iterator begin, end; + aStr.BeginReading(begin); + aStr.EndReading(end); +#else + const char *begin, *end; + PRUint32 len = NS_CStringGetData(aStr, &begin); + end = begin + len; +#endif + + while (begin != end) { + code = AddToHash(code, *begin); + ++begin; + } + + return code; +} + +PRUint32 +HashString(const char *str) +{ + PRUint32 code = 0; + const char *origStr = str; + + while (*str) { + code = AddToHash(code, *str); + ++str; + } + + return code; +} + +PRUint32 +HashString(const PRUnichar *str) +{ + PRUint32 code = 0; + const PRUnichar *origStr = str; + + while (*str) { + code = AddToHash(code, *str); + ++str; + } + + return code; +} PLDHashOperator PL_DHashStubEnumRemove(PLDHashTable *table, @@ -45,3 +124,17 @@ PL_DHashStubEnumRemove(PLDHashTable *table, { return PL_DHASH_REMOVE; } + +PRUint32 nsIDHashKey::HashKey(const nsID* id) +{ + PRUint32 h = id->m0; + PRUint32 i; + + h = PR_ROTATE_LEFT32(h, 4) ^ id->m1; + h = PR_ROTATE_LEFT32(h, 4) ^ id->m2; + + for (i = 0; i < 8; i++) + h = PR_ROTATE_LEFT32(h, 4) ^ id->m3[i]; + + return h; +} diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index 0f5b1e14ee71..f10f696541b6 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -126,7 +126,13 @@ PL_DHashFreeTable(PLDHashTable *table, void *ptr) PLDHashNumber PL_DHashStringKey(PLDHashTable *table, const void *key) { - return HashString(static_cast(key)); + PLDHashNumber h; + const unsigned char *s; + + h = 0; + for (s = (const unsigned char *) key; *s != '\0'; s++) + h = AddToHash(h, *s); + return h; } PLDHashNumber diff --git a/xpcom/io/nsLocalFileOS2.cpp b/xpcom/io/nsLocalFileOS2.cpp index 4e2778b4a398..2a09bf1cb39b 100644 --- a/xpcom/io/nsLocalFileOS2.cpp +++ b/xpcom/io/nsLocalFileOS2.cpp @@ -59,8 +59,6 @@ #include "nsIMutableArray.h" #include "nsTraceRefcntImpl.h" -using namespace mozilla; - #define CHECK_mWorkingPath() \ PR_BEGIN_MACRO \ if (mWorkingPath.IsEmpty()) \ @@ -2577,7 +2575,7 @@ nsLocalFile::Equals(nsIHashable* aOther, bool *aResult) NS_IMETHODIMP nsLocalFile::GetHashCode(PRUint32 *aResult) { - *aResult = HashString(mWorkingPath); + *aResult = nsCRT::HashCode(mWorkingPath.get()); return NS_OK; } diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp index 60418a71d65c..9f51762b6410 100644 --- a/xpcom/io/nsLocalFileUnix.cpp +++ b/xpcom/io/nsLocalFileUnix.cpp @@ -121,7 +121,6 @@ static nsresult MacErrorMapper(OSErr inErr); #include "nsNativeCharsetUtils.h" #include "nsTraceRefcntImpl.h" -#include "nsHashKeys.h" using namespace mozilla; @@ -2031,7 +2030,7 @@ nsLocalFile::Equals(nsIHashable* aOther, bool *aResult) NS_IMETHODIMP nsLocalFile::GetHashCode(PRUint32 *aResult) { - *aResult = HashString(mPath); + *aResult = nsCRT::HashCode(mPath.get()); return NS_OK; } diff --git a/xpcom/tests/TestHashtables.cpp b/xpcom/tests/TestHashtables.cpp index 1d0c30ad1508..e53145df68c1 100644 --- a/xpcom/tests/TestHashtables.cpp +++ b/xpcom/tests/TestHashtables.cpp @@ -107,7 +107,7 @@ public: bool KeyEquals(const char* aEntity) const { return !strcmp(mNode->mStr, aEntity); } static const char* KeyToPointer(const char* aEntity) { return aEntity; } - static PLDHashNumber HashKey(const char* aEntity) { return mozilla::HashString(aEntity); } + static PLDHashNumber HashKey(const char* aEntity) { return HashString(aEntity); } enum { ALLOW_MEMMOVE = true }; const EntityNode* mNode; diff --git a/xpcom/tests/TestUTF.cpp b/xpcom/tests/TestUTF.cpp index f01bb6f34af5..2729a2f4401b 100644 --- a/xpcom/tests/TestUTF.cpp +++ b/xpcom/tests/TestUTF.cpp @@ -41,9 +41,9 @@ #include "nsString.h" #include "nsStringBuffer.h" #include "nsReadableUtils.h" +#include "nsCRTGlue.h" #include "UTFStrings.h" -#include "nsUnicharUtils.h" -#include "mozilla/HashFunctions.h" +#include "nsCRT.h" using namespace mozilla; @@ -153,8 +153,8 @@ test_hashas16() for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) { nsDependentCString str8(ValidStrings[i].m8); bool err; - if (HashString(ValidStrings[i].m16) != - HashUTF8AsUTF16(str8.get(), str8.Length(), &err) || + if (nsCRT::HashCode(ValidStrings[i].m16) != + nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) || err) return false; } @@ -162,8 +162,8 @@ test_hashas16() for (unsigned int i = 0; i < ArrayLength(Invalid8Strings); ++i) { nsDependentCString str8(Invalid8Strings[i].m8); bool err; - if (HashString(Invalid8Strings[i].m16) != - HashUTF8AsUTF16(str8.get(), str8.Length(), &err) || + if (nsCRT::HashCode(Invalid8Strings[i].m16) != + nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) || err) return false; } @@ -173,7 +173,7 @@ test_hashas16() for (unsigned int i = 0; i < ArrayLength(Malformed8Strings); ++i) { nsDependentCString str8(Malformed8Strings[i]); bool err; - if (HashUTF8AsUTF16(str8.get(), str8.Length(), &err) != 0 || + if (nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) != 0 || !err) return false; }