summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/PropertySlot.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/PropertySlot.h')
-rw-r--r--Source/JavaScriptCore/runtime/PropertySlot.h143
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