diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/PropertySlot.h')
| -rw-r--r-- | Source/JavaScriptCore/runtime/PropertySlot.h | 143 |
1 files changed, 106 insertions, 37 deletions
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.h b/Source/JavaScriptCore/runtime/PropertySlot.h index ae93455a4..7e7ee058b 100644 --- a/Source/JavaScriptCore/runtime/PropertySlot.h +++ b/Source/JavaScriptCore/runtime/PropertySlot.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2007, 2008, 2015 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,42 +31,72 @@ namespace JSC { class ExecState; class GetterSetter; +class JSObject; // ECMA 262-3 8.6.1 // Property attributes enum Attribute { - None = 0, - ReadOnly = 1 << 1, // property can be only read, not written - DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) - DontDelete = 1 << 3, // property can't be deleted - Function = 1 << 4, // property is a function - only used by static hashtables - Accessor = 1 << 5, // property is a getter/setter + None = 0, + ReadOnly = 1 << 1, // property can be only read, not written + DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) + DontDelete = 1 << 3, // property can't be deleted + Accessor = 1 << 4, // property is a getter/setter + CustomAccessor = 1 << 5, + + // Things that are used by static hashtables are not in the attributes byte in PropertyMapEntry. + Function = 1 << 8, // property is a function - only used by static hashtables + Builtin = 1 << 9, // property is a builtin function - only used by static hashtables + ConstantInteger = 1 << 10, // property is a constant integer - only used by static hashtables + BuiltinOrFunction = Builtin | Function, // helper only used by static hashtables + BuiltinOrFunctionOrAccessor = Builtin | Function | Accessor, // helper only used by static hashtables + BuiltinOrFunctionOrAccessorOrConstant = Builtin | Function | Accessor | ConstantInteger, // helper only used by static hashtables }; +inline unsigned attributesForStructure(unsigned attributes) +{ + // The attributes that are used just for the static hashtable are at bit 8 and higher. + return static_cast<uint8_t>(attributes); +} + class PropertySlot { - enum PropertyType { + enum PropertyType : uint8_t { TypeUnset, TypeValue, TypeGetter, - TypeCustom, - TypeCustomIndex + TypeCustom + }; + + enum CacheabilityType : uint8_t { + CachingDisallowed, + CachingAllowed }; public: - explicit PropertySlot(const JSValue thisValue) - : m_propertyType(TypeUnset) - , m_offset(invalidOffset) + enum class InternalMethodType : uint8_t { + Get, // [[Get]] internal method in the spec. + HasProperty, // [[HasProperty]] internal method in the spec. + GetOwnProperty, // [[GetOwnProperty]] internal method in the spec. + VMInquiry, // Our VM is just poking around. When this is the InternalMethodType, getOwnPropertySlot is not allowed to do user observable actions. + }; + + explicit PropertySlot(const JSValue thisValue, InternalMethodType internalMethodType) + : m_offset(invalidOffset) , m_thisValue(thisValue) + , m_slotBase(nullptr) + , m_watchpointSet(nullptr) + , m_cacheability(CachingAllowed) + , m_propertyType(TypeUnset) + , m_internalMethodType(internalMethodType) { } - typedef EncodedJSValue (*GetValueFunc)(ExecState*, EncodedJSValue slotBase, EncodedJSValue thisValue, PropertyName); - typedef EncodedJSValue (*GetIndexValueFunc)(ExecState*, EncodedJSValue slotBase, EncodedJSValue thisValue, unsigned); + typedef EncodedJSValue (*GetValueFunc)(ExecState*, EncodedJSValue thisValue, PropertyName); JSValue getValue(ExecState*, PropertyName) const; JSValue getValue(ExecState*, unsigned propertyName) const; - bool isCacheable() const { return m_offset != invalidOffset; } + bool isCacheable() const { return m_cacheability == CachingAllowed && m_offset != invalidOffset; } + bool isUnset() const { return m_propertyType == TypeUnset; } bool isValue() const { return m_propertyType == TypeValue; } bool isAccessor() const { return m_propertyType == TypeGetter; } bool isCustom() const { return m_propertyType == TypeCustom; } @@ -74,6 +104,13 @@ public: bool isCacheableGetter() const { return isCacheable() && isAccessor(); } bool isCacheableCustom() const { return isCacheable() && isCustom(); } + InternalMethodType internalMethodType() const { return m_internalMethodType; } + + void disableCaching() + { + m_cacheability = CachingDisallowed; + } + unsigned attributes() const { return m_attributes; } PropertyOffset cachedOffset() const @@ -96,13 +133,18 @@ public: JSObject* slotBase() const { - ASSERT(m_propertyType != TypeUnset); return m_slotBase; } + WatchpointSet* watchpointSet() const + { + return m_watchpointSet; + } + void setValue(JSObject* slotBase, unsigned attributes, JSValue value) { - ASSERT(value); + ASSERT(attributes == attributesForStructure(attributes)); + m_data.value = JSValue::encode(value); m_attributes = attributes; @@ -114,6 +156,8 @@ public: void setValue(JSObject* slotBase, unsigned attributes, JSValue value, PropertyOffset offset) { + ASSERT(attributes == attributesForStructure(attributes)); + ASSERT(value); m_data.value = JSValue::encode(value); m_attributes = attributes; @@ -126,6 +170,8 @@ public: void setValue(JSString*, unsigned attributes, JSValue value) { + ASSERT(attributes == attributesForStructure(attributes)); + ASSERT(value); m_data.value = JSValue::encode(value); m_attributes = attributes; @@ -137,6 +183,8 @@ public: void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue) { + ASSERT(attributes == attributesForStructure(attributes)); + ASSERT(getValue); m_data.custom.getValue = getValue; m_attributes = attributes; @@ -149,6 +197,8 @@ public: void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue) { + ASSERT(attributes == attributesForStructure(attributes)); + ASSERT(getValue); m_data.custom.getValue = getValue; m_attributes = attributes; @@ -159,21 +209,10 @@ public: m_offset = !invalidOffset; } - void setCustomIndex(JSObject* slotBase, unsigned attributes, unsigned index, GetIndexValueFunc getIndexValue) - { - ASSERT(getIndexValue); - m_data.customIndex.getIndexValue = getIndexValue; - m_data.customIndex.index = index; - m_attributes = attributes; - - ASSERT(slotBase); - m_slotBase = slotBase; - m_propertyType = TypeCustomIndex; - m_offset = invalidOffset; - } - void setGetterSlot(JSObject* slotBase, unsigned attributes, GetterSetter* getterSetter) { + ASSERT(attributes == attributesForStructure(attributes)); + ASSERT(getterSetter); m_data.getter.getterSetter = getterSetter; m_attributes = attributes; @@ -186,6 +225,8 @@ public: void setCacheableGetterSlot(JSObject* slotBase, unsigned attributes, GetterSetter* getterSetter, PropertyOffset offset) { + ASSERT(attributes == attributesForStructure(attributes)); + ASSERT(getterSetter); m_data.getter.getterSetter = getterSetter; m_attributes = attributes; @@ -196,6 +237,11 @@ public: m_offset = offset; } + void setThisValue(JSValue thisValue) + { + m_thisValue = thisValue; + } + void setUndefined() { m_data.value = JSValue::encode(jsUndefined()); @@ -206,8 +252,14 @@ public: m_offset = invalidOffset; } + void setWatchpointSet(WatchpointSet& set) + { + m_watchpointSet = &set; + } + private: JS_EXPORT_PRIVATE JSValue functionGetter(ExecState*) const; + JS_EXPORT_PRIVATE JSValue customGetter(ExecState*, PropertyName) const; unsigned m_attributes; union { @@ -218,18 +270,35 @@ private: struct { GetValueFunc getValue; } custom; - struct { - GetIndexValueFunc getIndexValue; - unsigned index; - } customIndex; } m_data; - PropertyType m_propertyType; PropertyOffset m_offset; - const JSValue m_thisValue; + JSValue m_thisValue; JSObject* m_slotBase; + WatchpointSet* m_watchpointSet; + CacheabilityType m_cacheability; + PropertyType m_propertyType; + InternalMethodType m_internalMethodType; }; +ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, PropertyName propertyName) const +{ + if (m_propertyType == TypeValue) + return JSValue::decode(m_data.value); + if (m_propertyType == TypeGetter) + return functionGetter(exec); + return customGetter(exec, propertyName); +} + +ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, unsigned propertyName) const +{ + if (m_propertyType == TypeValue) + return JSValue::decode(m_data.value); + if (m_propertyType == TypeGetter) + return functionGetter(exec); + return customGetter(exec, Identifier::from(exec, propertyName)); +} + } // namespace JSC #endif // PropertySlot_h |
