X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..217a6308cd6a1dc049a0bb69263bd4c91f91c4d0:/runtime/PropertySlot.h?ds=sidebyside diff --git a/runtime/PropertySlot.h b/runtime/PropertySlot.h index 1dd1afa..6fb80d2 100644 --- a/runtime/PropertySlot.h +++ b/runtime/PropertySlot.h @@ -21,9 +21,9 @@ #ifndef PropertySlot_h #define PropertySlot_h -#include "Identifier.h" -#include "JSValue.h" -#include "JSImmediate.h" +#include "JSCJSValue.h" +#include "PropertyName.h" +#include "PropertyOffset.h" #include "Register.h" #include #include @@ -33,141 +33,156 @@ namespace JSC { class ExecState; class JSObject; -#define JSC_VALUE_SLOT_MARKER 0 -#define JSC_REGISTER_SLOT_MARKER reinterpret_cast(1) +#define JSC_VALUE_MARKER 0 +#define INDEX_GETTER_MARKER reinterpret_cast(2) +#define GETTER_FUNCTION_MARKER reinterpret_cast(3) class PropertySlot { public: + enum CachedPropertyType { + Uncacheable, + Getter, + Custom, + Value + }; + PropertySlot() - : m_offset(WTF::notFound) + : m_cachedPropertyType(Uncacheable) { clearBase(); + clearOffset(); clearValue(); } - explicit PropertySlot(const JSValuePtr base) + explicit PropertySlot(const JSValue base) : m_slotBase(base) - , m_offset(WTF::notFound) + , m_cachedPropertyType(Uncacheable) { + clearOffset(); clearValue(); } - typedef JSValuePtr (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&); + typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, PropertyName); + typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned); - JSValuePtr getValue(ExecState* exec, const Identifier& propertyName) const + JSValue getValue(ExecState* exec, PropertyName propertyName) const { - if (m_getValue == JSC_VALUE_SLOT_MARKER) - return *m_data.valueSlot; - if (m_getValue == JSC_REGISTER_SLOT_MARKER) - return (*m_data.registerSlot).jsValue(exec); - return m_getValue(exec, propertyName, *this); + if (m_getValue == JSC_VALUE_MARKER) + return m_value; + 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); } - JSValuePtr getValue(ExecState* exec, unsigned propertyName) const + JSValue getValue(ExecState* exec, unsigned propertyName) const { - if (m_getValue == JSC_VALUE_SLOT_MARKER) - return *m_data.valueSlot; - if (m_getValue == JSC_REGISTER_SLOT_MARKER) - return (*m_data.registerSlot).jsValue(exec); - return m_getValue(exec, Identifier::from(exec, propertyName), *this); + if (m_getValue == JSC_VALUE_MARKER) + return m_value; + 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; } - size_t cachedOffset() const + CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; } + bool isCacheable() const { return m_cachedPropertyType != Uncacheable; } + bool isCacheableValue() const { return m_cachedPropertyType == Value; } + PropertyOffset cachedOffset() const { ASSERT(isCacheable()); return m_offset; } - void putValue(JSValuePtr value) - { - if (m_getValue == JSC_VALUE_SLOT_MARKER) { - *m_data.valueSlot = value; - return; - } - ASSERT(m_getValue == JSC_REGISTER_SLOT_MARKER); - *m_data.registerSlot = JSValuePtr(value); - } - - void setValueSlot(JSValuePtr* valueSlot) - { - ASSERT(valueSlot); - m_getValue = JSC_VALUE_SLOT_MARKER; - clearBase(); - m_data.valueSlot = valueSlot; - } - - void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot) + void setValue(JSValue slotBase, JSValue value) { - ASSERT(valueSlot); - m_getValue = JSC_VALUE_SLOT_MARKER; + ASSERT(value); + clearOffset(); + m_getValue = JSC_VALUE_MARKER; m_slotBase = slotBase; - m_data.valueSlot = valueSlot; + m_value = value; } - void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot, size_t offset) + void setValue(JSValue slotBase, JSValue value, PropertyOffset offset) { - ASSERT(valueSlot); - m_getValue = JSC_VALUE_SLOT_MARKER; + ASSERT(value); + m_getValue = JSC_VALUE_MARKER; m_slotBase = slotBase; - m_data.valueSlot = valueSlot; + m_value = value; m_offset = offset; + m_cachedPropertyType = Value; } - - void setValue(JSValuePtr value) + + void setValue(JSValue value) { ASSERT(value); - m_getValue = JSC_VALUE_SLOT_MARKER; clearBase(); + clearOffset(); + m_getValue = JSC_VALUE_MARKER; m_value = value; - m_data.valueSlot = &m_value; } - void setRegisterSlot(Register* registerSlot) + void setCustom(JSValue slotBase, GetValueFunc getValue) { - ASSERT(registerSlot); - m_getValue = JSC_REGISTER_SLOT_MARKER; - clearBase(); - m_data.registerSlot = registerSlot; + ASSERT(slotBase); + ASSERT(getValue); + m_getValue = getValue; + m_getIndexValue = 0; + m_slotBase = slotBase; } - - void setCustom(JSValuePtr slotBase, 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(JSValuePtr slotBase, unsigned index, GetValueFunc getValue) + void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue) { ASSERT(slotBase); - ASSERT(getValue); - m_getValue = getValue; + 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, PropertyOffset 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() { - clearBase(); setValue(jsUndefined()); } - JSValuePtr slotBase() const + JSValue slotBase() const { - ASSERT(m_slotBase); return m_slotBase; } - void setBase(JSValuePtr base) + void setBase(JSValue base) { ASSERT(m_slotBase); ASSERT(base); @@ -177,35 +192,49 @@ namespace JSC { void clearBase() { #ifndef NDEBUG - m_slotBase = noValue(); + m_slotBase = JSValue(); #endif } void clearValue() { #ifndef NDEBUG - m_value = noValue(); + m_value = JSValue(); #endif } + void clearOffset() + { + // 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 = invalidOffset; + m_cachedPropertyType = Uncacheable; + } + unsigned index() const { return m_data.index; } + GetValueFunc customGetter() const + { + ASSERT(m_cachedPropertyType == Custom); + return m_getValue; + } private: - static JSValuePtr functionGetter(ExecState*, const Identifier&, const PropertySlot&); + JS_EXPORT_PRIVATE JSValue functionGetter(ExecState*) const; GetValueFunc m_getValue; + GetIndexValueFunc m_getIndexValue; - JSValuePtr m_slotBase; + JSValue m_slotBase; union { JSObject* getterFunc; - JSValuePtr* valueSlot; - Register* registerSlot; unsigned index; } m_data; - JSValuePtr m_value; + JSValue m_value; + JSValue m_thisValue; - size_t m_offset; + PropertyOffset m_offset; + CachedPropertyType m_cachedPropertyType; }; } // namespace JSC