diff options
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h')
-rw-r--r-- | src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h | 214 |
1 files changed, 139 insertions, 75 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h index 4743baf859..d015b9c512 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 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 @@ -23,11 +23,12 @@ #ifndef JSCell_h #define JSCell_h -#include <wtf/Noncopyable.h> -#include "Structure.h" -#include "JSValue.h" -#include "JSImmediate.h" #include "Collector.h" +#include "JSImmediate.h" +#include "JSValue.h" +#include "MarkStack.h" +#include "Structure.h" +#include <wtf/Noncopyable.h> namespace JSC { @@ -40,19 +41,24 @@ namespace JSC { friend class JSPropertyNameIterator; friend class JSString; friend class JSValue; - friend class VPtrSet; + friend class JSAPIValueWrapper; + friend struct VPtrSet; private: explicit JSCell(Structure*); + JSCell(); // Only used for initializing Collector blocks. virtual ~JSCell(); public: // Querying the type. +#if USE(JSVALUE32) bool isNumber() const; +#endif bool isString() const; bool isObject() const; virtual bool isGetterSetter() const; - virtual bool isObject(const ClassInfo*) const; + bool inherits(const ClassInfo*) const; + virtual bool isAPIValueWrapper() const { return false; } Structure* structure() const; @@ -68,23 +74,21 @@ namespace JSC { // Extracting integer values. // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*. virtual bool getUInt32(uint32_t&) const; - virtual bool getTruncatedInt32(int32_t&) const; - virtual bool getTruncatedUInt32(uint32_t&) const; // Basic conversions. - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const = 0; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&) = 0; - virtual bool toBoolean(ExecState*) const = 0; - virtual double toNumber(ExecState*) const = 0; - virtual UString toString(ExecState*) const = 0; - virtual JSObject* toObject(ExecState*) const = 0; + virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; + virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&); + virtual bool toBoolean(ExecState*) const; + virtual double toNumber(ExecState*) const; + virtual UString toString(ExecState*) const; + virtual JSObject* toObject(ExecState*) const; // Garbage collection. void* operator new(size_t, ExecState*); void* operator new(size_t, JSGlobalData*); void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; } - virtual void mark(); - bool marked() const; + + virtual void markChildren(MarkStack&); // Object operations, with the toObject operation included. virtual const ClassInfo* classInfo() const; @@ -108,6 +112,7 @@ namespace JSC { Structure* m_structure; }; + // FIXME: We should deprecate this and just use JSValue::asCell() instead. JSCell* asCell(JSValue); inline JSCell* asCell(JSValue value) @@ -120,14 +125,21 @@ namespace JSC { { } + // Only used for initializing Collector blocks. + inline JSCell::JSCell() + { + } + inline JSCell::~JSCell() { } +#if USE(JSVALUE32) inline bool JSCell::isNumber() const { return Heap::isNumber(const_cast<JSCell*>(this)); } +#endif inline bool JSCell::isObject() const { @@ -144,20 +156,8 @@ namespace JSC { return m_structure; } - inline bool JSCell::marked() const + inline void JSCell::markChildren(MarkStack&) { - return Heap::isCellMarked(this); - } - - inline void JSCell::mark() - { - return Heap::markCell(this); - } - - ALWAYS_INLINE JSCell* JSValue::asCell() const - { - ASSERT(isCell()); - return m_ptr; } inline void* JSCell::operator new(size_t size, JSGlobalData* globalData) @@ -173,126 +173,190 @@ namespace JSC { inline bool JSValue::isString() const { - return !JSImmediate::isImmediate(asValue()) && asCell()->isString(); + return isCell() && asCell()->isString(); } inline bool JSValue::isGetterSetter() const { - return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter(); + return isCell() && asCell()->isGetterSetter(); } inline bool JSValue::isObject() const { - return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(); + return isCell() && asCell()->isObject(); } inline bool JSValue::getString(UString& s) const { - return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s); + return isCell() && asCell()->getString(s); } inline UString JSValue::getString() const { - return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString(); + return isCell() ? asCell()->getString() : UString(); } inline JSObject* JSValue::getObject() const { - return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject(); + return isCell() ? asCell()->getObject() : 0; } inline CallType JSValue::getCallData(CallData& callData) { - return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData); + return isCell() ? asCell()->getCallData(callData) : CallTypeNone; } inline ConstructType JSValue::getConstructData(ConstructData& constructData) { - return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData); + return isCell() ? asCell()->getConstructData(constructData) : ConstructTypeNone; } ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v); + if (isInt32()) { + int32_t i = asInt32(); + v = static_cast<uint32_t>(i); + return i >= 0; + } + if (isDouble()) { + double d = asDouble(); + v = static_cast<uint32_t>(d); + return v == d; + } + return false; } - ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const +#if !USE(JSVALUE32_64) + ALWAYS_INLINE JSCell* JSValue::asCell() const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v); + ASSERT(isCell()); + return m_ptr; } +#endif // !USE(JSVALUE32_64) - inline bool JSValue::getTruncatedUInt32(uint32_t& v) const + inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v); + return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue(); } - inline void JSValue::mark() + inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) { - asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells + if (isInt32()) { + number = asInt32(); + value = *this; + return true; + } + if (isDouble()) { + number = asDouble(); + value = *this; + return true; + } + if (isCell()) + return asCell()->getPrimitiveNumber(exec, number, value); + if (isTrue()) { + number = 1.0; + value = *this; + return true; + } + if (isFalse() || isNull()) { + number = 0.0; + value = *this; + return true; + } + ASSERT(isUndefined()); + number = nonInlineNaN(); + value = *this; + return true; } - inline bool JSValue::marked() const + inline bool JSValue::toBoolean(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) || asCell()->marked(); + if (isInt32()) + return asInt32() != 0; + if (isDouble()) + return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN + if (isCell()) + return asCell()->toBoolean(exec); + return isTrue(); // false, null, and undefined all convert to false. } - inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const + ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType); + if (isInt32()) + return asInt32(); + if (isDouble()) + return asDouble(); + if (isCell()) + return asCell()->toNumber(exec); + if (isTrue()) + return 1.0; + return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0. } - inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) + inline bool JSValue::needsThisConversion() const { - if (JSImmediate::isImmediate(asValue())) { - number = JSImmediate::toDouble(asValue()); - value = asValue(); + if (UNLIKELY(!isCell())) return true; - } - return asCell()->getPrimitiveNumber(exec, number, value); + return asCell()->structure()->typeInfo().needsThisConversion(); } - inline bool JSValue::toBoolean(ExecState* exec) const + inline UString JSValue::toThisString(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec); + return isCell() ? asCell()->toThisString(exec) : toString(exec); } - ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const + inline JSValue JSValue::getJSNumber() { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec); + if (isInt32() || isDouble()) + return *this; + if (isCell()) + return asCell()->getJSNumber(); + return JSValue(); } - inline UString JSValue::toString(ExecState* exec) const + inline JSObject* JSValue::toObject(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec); + return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec); } - inline JSObject* JSValue::toObject(ExecState* exec) const + inline JSObject* JSValue::toThisObject(ExecState* exec) const { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec); + return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec); } - inline JSObject* JSValue::toThisObject(ExecState* exec) const + ALWAYS_INLINE void MarkStack::append(JSCell* cell) { - if (UNLIKELY(JSImmediate::isImmediate(asValue()))) - return JSImmediate::toThisObject(asValue(), exec); - return asCell()->toThisObject(exec); + ASSERT(!m_isCheckingForDefaultMarkViolation); + ASSERT(cell); + if (Heap::isCellMarked(cell)) + return; + Heap::markCell(cell); + if (cell->structure()->typeInfo().type() >= CompoundType) + m_values.append(cell); } - inline bool JSValue::needsThisConversion() const + ALWAYS_INLINE void MarkStack::append(JSValue value) { - if (UNLIKELY(JSImmediate::isImmediate(asValue()))) - return true; - return asCell()->structure()->typeInfo().needsThisConversion(); + ASSERT(value); + if (value.isCell()) + append(value.asCell()); } - inline UString JSValue::toThisString(ExecState* exec) const + inline void Structure::markAggregate(MarkStack& markStack) { - return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec); + markStack.append(m_prototype); } - inline JSValue JSValue::getJSNumber() + inline Heap* Heap::heap(JSValue v) + { + if (!v.isCell()) + return 0; + return heap(v.asCell()); + } + + inline Heap* Heap::heap(JSCell* c) { - return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? JSValue() : asCell()->getJSNumber(); + return cellBlock(c)->heap; } } // namespace JSC |