diff options
Diffstat (limited to 'JavaScriptCore/runtime/PropertySlot.h')
-rw-r--r-- | JavaScriptCore/runtime/PropertySlot.h | 80 |
1 files changed, 69 insertions, 11 deletions
diff --git a/JavaScriptCore/runtime/PropertySlot.h b/JavaScriptCore/runtime/PropertySlot.h index 15d9034..de9ddc9 100644 --- a/JavaScriptCore/runtime/PropertySlot.h +++ b/JavaScriptCore/runtime/PropertySlot.h @@ -34,10 +34,20 @@ namespace JSC { #define JSC_VALUE_SLOT_MARKER 0 #define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1) +#define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2) +#define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3) class PropertySlot { public: + enum CachedPropertyType { + Uncacheable, + Getter, + Custom, + Value + }; + PropertySlot() + : m_cachedPropertyType(Uncacheable) { clearBase(); clearOffset(); @@ -46,12 +56,14 @@ namespace JSC { explicit PropertySlot(const JSValue base) : m_slotBase(base) + , m_cachedPropertyType(Uncacheable) { clearOffset(); clearValue(); } - typedef JSValue (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&); + typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, const Identifier&); + typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned); JSValue getValue(ExecState* exec, const Identifier& propertyName) const { @@ -59,7 +71,11 @@ namespace JSC { return *m_data.valueSlot; if (m_getValue == JSC_REGISTER_SLOT_MARKER) return (*m_data.registerSlot).jsValue(); - return m_getValue(exec, propertyName, *this); + if (m_getValue == INDEX_GETTER_MARKER) + return m_getIndexValue(exec, slotBase(), index()); + if (m_getValue == GETTER_FUNCTION_MARKER) + return functionGetter(exec); + return m_getValue(exec, slotBase(), propertyName); } JSValue getValue(ExecState* exec, unsigned propertyName) const @@ -68,10 +84,16 @@ namespace JSC { return *m_data.valueSlot; if (m_getValue == JSC_REGISTER_SLOT_MARKER) return (*m_data.registerSlot).jsValue(); - return m_getValue(exec, Identifier::from(exec, propertyName), *this); + if (m_getValue == INDEX_GETTER_MARKER) + return m_getIndexValue(exec, m_slotBase, m_data.index); + if (m_getValue == GETTER_FUNCTION_MARKER) + return functionGetter(exec); + return m_getValue(exec, slotBase(), Identifier::from(exec, propertyName)); } - bool isCacheable() const { return m_offset != WTF::notFound; } + CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; } + bool isCacheable() const { return m_cachedPropertyType != Uncacheable; } + bool isCacheableValue() const { return m_cachedPropertyType == Value; } size_t cachedOffset() const { ASSERT(isCacheable()); @@ -102,6 +124,7 @@ namespace JSC { m_slotBase = slotBase; m_data.valueSlot = valueSlot; m_offset = offset; + m_cachedPropertyType = Value; } void setValue(JSValue value) @@ -128,25 +151,49 @@ namespace JSC { ASSERT(slotBase); ASSERT(getValue); m_getValue = getValue; + m_getIndexValue = 0; m_slotBase = slotBase; } - - void setCustomIndex(JSValue slotBase, unsigned index, GetValueFunc getValue) + + void setCacheableCustom(JSValue slotBase, GetValueFunc getValue) { ASSERT(slotBase); ASSERT(getValue); m_getValue = getValue; + m_getIndexValue = 0; + m_slotBase = slotBase; + m_cachedPropertyType = Custom; + } + + void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue) + { + ASSERT(slotBase); + ASSERT(getIndexValue); + m_getValue = INDEX_GETTER_MARKER; + m_getIndexValue = getIndexValue; m_slotBase = slotBase; m_data.index = index; } - + void setGetterSlot(JSObject* getterFunc) { ASSERT(getterFunc); - m_getValue = functionGetter; + m_thisValue = m_slotBase; + m_getValue = GETTER_FUNCTION_MARKER; m_data.getterFunc = getterFunc; } - + + void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset) + { + ASSERT(getterFunc); + m_getValue = GETTER_FUNCTION_MARKER; + m_thisValue = m_slotBase; + m_slotBase = slotBase; + m_data.getterFunc = getterFunc; + m_offset = offset; + m_cachedPropertyType = Getter; + } + void setUndefined() { setValue(jsUndefined()); @@ -182,15 +229,24 @@ namespace JSC { { // Clear offset even in release builds, in case this PropertySlot has been used before. // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.) - m_offset = WTF::notFound; + m_offset = 0; + m_cachedPropertyType = Uncacheable; } unsigned index() const { return m_data.index; } + JSValue thisValue() const { return m_thisValue; } + + GetValueFunc customGetter() const + { + ASSERT(m_cachedPropertyType == Custom); + return m_getValue; + } private: - static JSValue functionGetter(ExecState*, const Identifier&, const PropertySlot&); + JSValue functionGetter(ExecState*) const; GetValueFunc m_getValue; + GetIndexValueFunc m_getIndexValue; JSValue m_slotBase; union { @@ -201,8 +257,10 @@ namespace JSC { } m_data; JSValue m_value; + JSValue m_thisValue; size_t m_offset; + CachedPropertyType m_cachedPropertyType; }; } // namespace JSC |