diff options
Diffstat (limited to 'JavaScriptCore/runtime/JSValue.h')
-rw-r--r-- | JavaScriptCore/runtime/JSValue.h | 336 |
1 files changed, 267 insertions, 69 deletions
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h index 1172a1b..391425c 100644 --- a/JavaScriptCore/runtime/JSValue.h +++ b/JavaScriptCore/runtime/JSValue.h @@ -28,11 +28,15 @@ #include "CallData.h" #include "ConstructData.h" +#include <wtf/HashTraits.h> +#include <wtf/AlwaysInline.h> namespace JSC { class Identifier; class JSCell; + class JSGlobalData; + class JSImmediate; class JSObject; class JSString; class PropertySlot; @@ -44,15 +48,15 @@ namespace JSC { enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString }; - class JSImmediate; - class JSValueEncodedAsPointer; + typedef void* EncodedJSValue; - class JSValuePtr { + class JSValue { friend class JSImmediate; + friend struct JSValueHashTraits; - static JSValuePtr makeImmediate(intptr_t value) + static JSValue makeImmediate(intptr_t value) { - return JSValuePtr(reinterpret_cast<JSCell*>(value)); + return JSValue(reinterpret_cast<JSCell*>(value)); } intptr_t immediateValue() @@ -61,45 +65,49 @@ namespace JSC { } public: - JSValuePtr() - : m_ptr(0) - { - } - - JSValuePtr(JSCell* ptr) - : m_ptr(ptr) - { - } - - JSValuePtr(const JSCell* ptr) - : m_ptr(const_cast<JSCell*>(ptr)) - { - } - - operator bool() const - { - return m_ptr; - } - - bool operator==(const JSValuePtr other) const - { - return m_ptr == other.m_ptr; - } - - bool operator!=(const JSValuePtr other) const - { - return m_ptr != other.m_ptr; - } - - static JSValueEncodedAsPointer* encode(JSValuePtr value) - { - return reinterpret_cast<JSValueEncodedAsPointer*>(value.m_ptr); - } - - static JSValuePtr decode(JSValueEncodedAsPointer* ptr) - { - return JSValuePtr(reinterpret_cast<JSCell*>(ptr)); - } + enum JSNullTag { JSNull }; + enum JSUndefinedTag { JSUndefined }; + enum JSTrueTag { JSTrue }; + enum JSFalseTag { JSFalse }; + + static EncodedJSValue encode(JSValue value); + static JSValue decode(EncodedJSValue ptr); + + JSValue(); + JSValue(JSNullTag); + JSValue(JSUndefinedTag); + JSValue(JSTrueTag); + JSValue(JSFalseTag); + JSValue(JSCell* ptr); + JSValue(const JSCell* ptr); + + // Numbers + JSValue(ExecState*, double); + JSValue(ExecState*, char); + JSValue(ExecState*, unsigned char); + JSValue(ExecState*, short); + JSValue(ExecState*, unsigned short); + JSValue(ExecState*, int); + JSValue(ExecState*, unsigned); + JSValue(ExecState*, long); + JSValue(ExecState*, unsigned long); + JSValue(ExecState*, long long); + JSValue(ExecState*, unsigned long long); + JSValue(JSGlobalData*, double); + JSValue(JSGlobalData*, char); + JSValue(JSGlobalData*, unsigned char); + JSValue(JSGlobalData*, short); + JSValue(JSGlobalData*, unsigned short); + JSValue(JSGlobalData*, int); + JSValue(JSGlobalData*, unsigned); + JSValue(JSGlobalData*, long); + JSValue(JSGlobalData*, unsigned long); + JSValue(JSGlobalData*, long long); + JSValue(JSGlobalData*, unsigned long long); + + operator bool() const; + bool operator==(const JSValue other) const; + bool operator!=(const JSValue other) const; // Querying the type. bool isUndefined() const; @@ -130,15 +138,15 @@ namespace JSC { bool getTruncatedUInt32(uint32_t&) const; // Basic conversions. - JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; - bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&); + JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; + bool getPrimitiveNumber(ExecState*, double& number, JSValue&); bool toBoolean(ExecState*) const; // toNumber conversion is expected to be side effect free if an exception has // been set in the ExecState already. double toNumber(ExecState*) const; - JSValuePtr toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number. + JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number. UString toString(ExecState*) const; JSObject* toObject(ExecState*) const; @@ -161,44 +169,50 @@ namespace JSC { int32_t getInt32Fast() const; bool isUInt32Fast() const; uint32_t getUInt32Fast() const; - static JSValuePtr makeInt32Fast(int32_t); - static bool areBothInt32Fast(JSValuePtr, JSValuePtr); + static JSValue makeInt32Fast(int32_t); + static bool areBothInt32Fast(JSValue, JSValue); // Floating point conversions (this is a convenience method for webcore; // signle precision float is not a representation used in JS or JSC). float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); } + // API Mangled Numbers + bool isAPIMangledNumber(); + // Garbage collection. void mark(); bool marked() const; // Object operations, with the toObject operation included. - JSValuePtr get(ExecState*, const Identifier& propertyName) const; - JSValuePtr get(ExecState*, const Identifier& propertyName, PropertySlot&) const; - JSValuePtr get(ExecState*, unsigned propertyName) const; - JSValuePtr get(ExecState*, unsigned propertyName, PropertySlot&) const; - void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&); - void put(ExecState*, unsigned propertyName, JSValuePtr); + JSValue get(ExecState*, const Identifier& propertyName) const; + JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const; + JSValue get(ExecState*, unsigned propertyName) const; + JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const; + void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); + void put(ExecState*, unsigned propertyName, JSValue); bool needsThisConversion() const; JSObject* toThisObject(ExecState*) const; UString toThisString(ExecState*) const; JSString* toThisJSString(ExecState*); - static bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2); - static bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2); - static bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2); - static bool strictEqual(JSValuePtr v1, JSValuePtr v2); - static bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2); - static bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2); + static bool equal(ExecState* exec, JSValue v1, JSValue v2); + static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2); + static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2); + static bool strictEqual(JSValue v1, JSValue v2); + static bool strictEqualSlowCase(JSValue v1, JSValue v2); + static bool strictEqualSlowCaseInline(JSValue v1, JSValue v2); - JSValuePtr getJSNumber(); // noValue() if this is not a JSNumber or number object + JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object bool isCell() const; JSCell* asCell() const; private: - inline const JSValuePtr asValue() const { return *this; } + enum HashTableDeletedValueTag { HashTableDeletedValue }; + JSValue(HashTableDeletedValueTag); + + inline const JSValue asValue() const { return *this; } bool isDoubleNumber() const; double getDoubleNumber() const; @@ -206,16 +220,200 @@ namespace JSC { JSCell* m_ptr; }; - inline JSValuePtr noValue() + struct JSValueHashTraits : HashTraits<EncodedJSValue> { + static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } + static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } + }; + + // Stand-alone helper functions. + inline JSValue jsNull() + { + return JSValue(JSValue::JSNull); + } + + inline JSValue jsUndefined() + { + return JSValue(JSValue::JSUndefined); + } + + inline JSValue jsBoolean(bool b) + { + return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d) + { + return JSValue(exec, d); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i) + { + return JSValue(exec, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d) + { + return JSValue(globalData, d); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, char i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned char i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, short i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned short i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long long i) + { + return JSValue(globalData, i); + } + + ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long long i) { - return JSValuePtr(); + return JSValue(globalData, i); } - inline bool operator==(const JSValuePtr a, const JSCell* b) { return a == JSValuePtr(b); } - inline bool operator==(const JSCell* a, const JSValuePtr b) { return JSValuePtr(a) == b; } + inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); } + inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; } - inline bool operator!=(const JSValuePtr a, const JSCell* b) { return a != JSValuePtr(b); } - inline bool operator!=(const JSCell* a, const JSValuePtr b) { return JSValuePtr(a) != b; } + inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); } + inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; } + + // JSValue member functions. + inline EncodedJSValue JSValue::encode(JSValue value) + { + return reinterpret_cast<EncodedJSValue>(value.m_ptr); + } + + inline JSValue JSValue::decode(EncodedJSValue ptr) + { + return JSValue(reinterpret_cast<JSCell*>(ptr)); + } + + // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page. + inline JSValue::JSValue() + : m_ptr(0) + { + } + + // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page. + inline JSValue::JSValue(HashTableDeletedValueTag) + : m_ptr(reinterpret_cast<JSCell*>(0x4)) + { + } + + inline JSValue::JSValue(JSCell* ptr) + : m_ptr(ptr) + { + } + + inline JSValue::JSValue(const JSCell* ptr) + : m_ptr(const_cast<JSCell*>(ptr)) + { + } + + inline JSValue::operator bool() const + { + return m_ptr; + } + + inline bool JSValue::operator==(const JSValue other) const + { + return m_ptr == other.m_ptr; + } + + inline bool JSValue::operator!=(const JSValue other) const + { + return m_ptr != other.m_ptr; + } + + inline bool JSValue::isUndefined() const + { + return asValue() == jsUndefined(); + } + + inline bool JSValue::isNull() const + { + return asValue() == jsNull(); + } } // namespace JSC |