18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modify it under the terms of the GNU Library General Public 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef PropertySlot_h 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define PropertySlot_h 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Identifier.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSValue.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Register.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h> 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/NotFound.h> 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project class ExecState; 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project class JSObject; 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define JSC_VALUE_MARKER 0 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2) 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3) 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39cad810f21b803229eb11403f9209855525a25d57Steve Block class PropertySlot { 40cad810f21b803229eb11403f9209855525a25d57Steve Block public: 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project enum CachedPropertyType { 42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Uncacheable, 43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Getter, 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Custom, 45d0825bca7fe65beaee391d30da42e937db621564Steve Block Value 462bde8e466a4451c7319e3a072d118917957d6554Steve Block }; 472bde8e466a4451c7319e3a072d118917957d6554Steve Block 482bde8e466a4451c7319e3a072d118917957d6554Steve Block PropertySlot() 49d0825bca7fe65beaee391d30da42e937db621564Steve Block : m_cachedPropertyType(Uncacheable) 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block clearBase(); 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clearOffset(); 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block clearValue(); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 55e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block explicit PropertySlot(const JSValue base) 57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block : m_slotBase(base) 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_cachedPropertyType(Uncacheable) 59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block clearOffset(); 61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block clearValue(); 62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, const Identifier&); 65d0825bca7fe65beaee391d30da42e937db621564Steve Block typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned); 6668513a70bcd92384395513322f1b801e7bf9c729Steve Block 67692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue getValue(ExecState* exec, const Identifier& propertyName) const 68d0825bca7fe65beaee391d30da42e937db621564Steve Block { 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_getValue == JSC_VALUE_MARKER) 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_value; 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_getValue == INDEX_GETTER_MARKER) 72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return m_getIndexValue(exec, slotBase(), index()); 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_getValue == GETTER_FUNCTION_MARKER) 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return functionGetter(exec); 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_getValue(exec, slotBase(), propertyName); 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSValue getValue(ExecState* exec, unsigned propertyName) const 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_getValue == JSC_VALUE_MARKER) 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_value; 8268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (m_getValue == INDEX_GETTER_MARKER) 8368513a70bcd92384395513322f1b801e7bf9c729Steve Block return m_getIndexValue(exec, m_slotBase, m_data.index); 8468513a70bcd92384395513322f1b801e7bf9c729Steve Block if (m_getValue == GETTER_FUNCTION_MARKER) 8568513a70bcd92384395513322f1b801e7bf9c729Steve Block return functionGetter(exec); 8668513a70bcd92384395513322f1b801e7bf9c729Steve Block return m_getValue(exec, slotBase(), Identifier::from(exec, propertyName)); 8768513a70bcd92384395513322f1b801e7bf9c729Steve Block } 8868513a70bcd92384395513322f1b801e7bf9c729Steve Block 8968513a70bcd92384395513322f1b801e7bf9c729Steve Block CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; } 9068513a70bcd92384395513322f1b801e7bf9c729Steve Block bool isCacheable() const { return m_cachedPropertyType != Uncacheable; } 9168513a70bcd92384395513322f1b801e7bf9c729Steve Block bool isCacheableValue() const { return m_cachedPropertyType == Value; } 9268513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t cachedOffset() const 93d0825bca7fe65beaee391d30da42e937db621564Steve Block { 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(isCacheable()); 95d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_offset; 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project void setValue(JSValue slotBase, JSValue value) 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(value); 101 clearOffset(); 102 m_getValue = JSC_VALUE_MARKER; 103 m_slotBase = slotBase; 104 m_value = value; 105 } 106 107 void setValue(JSValue slotBase, JSValue value, size_t offset) 108 { 109 ASSERT(value); 110 m_getValue = JSC_VALUE_MARKER; 111 m_slotBase = slotBase; 112 m_value = value; 113 m_offset = offset; 114 m_cachedPropertyType = Value; 115 } 116 117 void setValue(JSValue value) 118 { 119 ASSERT(value); 120 clearBase(); 121 clearOffset(); 122 m_getValue = JSC_VALUE_MARKER; 123 m_value = value; 124 } 125 126 void setCustom(JSValue slotBase, GetValueFunc getValue) 127 { 128 ASSERT(slotBase); 129 ASSERT(getValue); 130 m_getValue = getValue; 131 m_getIndexValue = 0; 132 m_slotBase = slotBase; 133 } 134 135 void setCacheableCustom(JSValue slotBase, GetValueFunc getValue) 136 { 137 ASSERT(slotBase); 138 ASSERT(getValue); 139 m_getValue = getValue; 140 m_getIndexValue = 0; 141 m_slotBase = slotBase; 142 m_cachedPropertyType = Custom; 143 } 144 145 void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue) 146 { 147 ASSERT(slotBase); 148 ASSERT(getIndexValue); 149 m_getValue = INDEX_GETTER_MARKER; 150 m_getIndexValue = getIndexValue; 151 m_slotBase = slotBase; 152 m_data.index = index; 153 } 154 155 void setGetterSlot(JSObject* getterFunc) 156 { 157 ASSERT(getterFunc); 158 m_thisValue = m_slotBase; 159 m_getValue = GETTER_FUNCTION_MARKER; 160 m_data.getterFunc = getterFunc; 161 } 162 163 void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset) 164 { 165 ASSERT(getterFunc); 166 m_getValue = GETTER_FUNCTION_MARKER; 167 m_thisValue = m_slotBase; 168 m_slotBase = slotBase; 169 m_data.getterFunc = getterFunc; 170 m_offset = offset; 171 m_cachedPropertyType = Getter; 172 } 173 174 void setUndefined() 175 { 176 setValue(jsUndefined()); 177 } 178 179 JSValue slotBase() const 180 { 181 return m_slotBase; 182 } 183 184 void setBase(JSValue base) 185 { 186 ASSERT(m_slotBase); 187 ASSERT(base); 188 m_slotBase = base; 189 } 190 191 void clearBase() 192 { 193#ifndef NDEBUG 194 m_slotBase = JSValue(); 195#endif 196 } 197 198 void clearValue() 199 { 200#ifndef NDEBUG 201 m_value = JSValue(); 202#endif 203 } 204 205 void clearOffset() 206 { 207 // Clear offset even in release builds, in case this PropertySlot has been used before. 208 // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.) 209 m_offset = 0; 210 m_cachedPropertyType = Uncacheable; 211 } 212 213 unsigned index() const { return m_data.index; } 214 215 JSValue thisValue() const { return m_thisValue; } 216 217 GetValueFunc customGetter() const 218 { 219 ASSERT(m_cachedPropertyType == Custom); 220 return m_getValue; 221 } 222 private: 223 JSValue functionGetter(ExecState*) const; 224 225 GetValueFunc m_getValue; 226 GetIndexValueFunc m_getIndexValue; 227 228 JSValue m_slotBase; 229 union { 230 JSObject* getterFunc; 231 unsigned index; 232 } m_data; 233 234 JSValue m_value; 235 JSValue m_thisValue; 236 237 size_t m_offset; 238 CachedPropertyType m_cachedPropertyType; 239 }; 240 241} // namespace JSC 242 243#endif // PropertySlot_h 244