1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef PropertyName_h 27#define PropertyName_h 28 29#include "Identifier.h" 30#include "PrivateName.h" 31 32namespace JSC { 33 34template <typename CharType> 35ALWAYS_INLINE uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length) 36{ 37 // An empty string is not a number. 38 if (!length) 39 return UINT_MAX; 40 41 // Get the first character, turning it into a digit. 42 uint32_t value = characters[0] - '0'; 43 if (value > 9) 44 return UINT_MAX; 45 46 // Check for leading zeros. If the first characher is 0, then the 47 // length of the string must be one - e.g. "042" is not equal to "42". 48 if (!value && length > 1) 49 return UINT_MAX; 50 51 while (--length) { 52 // Multiply value by 10, checking for overflow out of 32 bits. 53 if (value > 0xFFFFFFFFU / 10) 54 return UINT_MAX; 55 value *= 10; 56 57 // Get the next character, turning it into a digit. 58 uint32_t newValue = *(++characters) - '0'; 59 if (newValue > 9) 60 return UINT_MAX; 61 62 // Add in the old value, checking for overflow out of 32 bits. 63 newValue += value; 64 if (newValue < value) 65 return UINT_MAX; 66 value = newValue; 67 } 68 69 return value; 70} 71 72ALWAYS_INLINE uint32_t toUInt32FromStringImpl(StringImpl* impl) 73{ 74 if (impl->is8Bit()) 75 return toUInt32FromCharacters(impl->characters8(), impl->length()); 76 return toUInt32FromCharacters(impl->characters16(), impl->length()); 77} 78 79class PropertyName { 80public: 81 PropertyName(const Identifier& propertyName) 82 : m_impl(propertyName.impl()) 83 { 84 ASSERT(!m_impl || m_impl->isIdentifier()); 85 } 86 87 PropertyName(const PrivateName& propertyName) 88 : m_impl(propertyName.uid()) 89 { 90 ASSERT(m_impl && m_impl->isEmptyUnique()); 91 } 92 93 StringImpl* uid() const 94 { 95 ASSERT(!m_impl || (m_impl->isIdentifier() == !m_impl->isEmptyUnique())); 96 return m_impl; 97 } 98 99 StringImpl* publicName() const 100 { 101 ASSERT(!m_impl || (m_impl->isIdentifier() == !m_impl->isEmptyUnique())); 102 return m_impl->isIdentifier() ? m_impl : 0; 103 } 104 105 static const uint32_t NotAnIndex = UINT_MAX; 106 107 uint32_t asIndex() 108 { 109 ASSERT(!m_impl || (m_impl->isIdentifier() == !m_impl->isEmptyUnique())); 110 return m_impl ? toUInt32FromStringImpl(m_impl) : NotAnIndex; 111 } 112 113private: 114 StringImpl* m_impl; 115}; 116 117inline bool operator==(PropertyName a, const Identifier& b) 118{ 119 return a.uid() == b.impl(); 120} 121 122inline bool operator==(const Identifier& a, PropertyName b) 123{ 124 return a.impl() == b.uid(); 125} 126 127inline bool operator==(PropertyName a, PropertyName b) 128{ 129 return a.uid() == b.uid(); 130} 131 132inline bool operator!=(PropertyName a, const Identifier& b) 133{ 134 return a.uid() != b.impl(); 135} 136 137inline bool operator!=(const Identifier& a, PropertyName b) 138{ 139 return a.impl() != b.uid(); 140} 141 142inline bool operator!=(PropertyName a, PropertyName b) 143{ 144 return a.uid() != b.uid(); 145} 146 147} 148 149#endif 150