diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSCell.h')
| -rw-r--r-- | Source/JavaScriptCore/runtime/JSCell.h | 107 |
1 files changed, 81 insertions, 26 deletions
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h index de85a4bdc..f98895d2a 100644 --- a/Source/JavaScriptCore/runtime/JSCell.h +++ b/Source/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, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 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 @@ -24,9 +24,13 @@ #define JSCell_h #include "CallData.h" +#include "CellState.h" #include "ConstructData.h" +#include "EnumerationMode.h" #include "Heap.h" +#include "IndexingType.h" #include "JSLock.h" +#include "JSTypeInfo.h" #include "SlotVisitor.h" #include "TypedArrayType.h" #include "WriteBarrier.h" @@ -36,6 +40,7 @@ namespace JSC { class CopyVisitor; class ExecState; +class Identifier; class JSArrayBufferView; class JSDestructibleObject; class JSGlobalObject; @@ -44,11 +49,6 @@ class PropertyDescriptor; class PropertyNameArray; class Structure; -enum EnumerationMode { - ExcludeDontEnumProperties, - IncludeDontEnumProperties -}; - template<typename T> void* allocateCell(Heap&); template<typename T> void* allocateCell(Heap&, size_t); @@ -74,7 +74,8 @@ public: static const unsigned StructureFlags = 0; static const bool needsDestruction = false; - static const bool hasImmortalStructure = false; + + static JSCell* seenMultipleCalleeObjects() { return bitwise_cast<JSCell*>(static_cast<uintptr_t>(1)); } enum CreatingEarlyCellTag { CreatingEarlyCell }; JSCell(CreatingEarlyCellTag); @@ -86,17 +87,27 @@ protected: public: // Querying the type. bool isString() const; + bool isSymbol() const; bool isObject() const; bool isGetterSetter() const; + bool isCustomGetterSetter() const; bool isProxy() const; bool inherits(const ClassInfo*) const; bool isAPIValueWrapper() const; + JSType type() const; + IndexingType indexingType() const; + StructureID structureID() const { return m_structureID; } Structure* structure() const; + Structure* structure(VM&) const; void setStructure(VM&, Structure*); - void clearStructure() { m_structure.clear(); } + void clearStructure() { m_structureID = 0; } + + TypeInfo::InlineTypeFlags inlineTypeFlags() const { return m_flags; } - const char* className(); + const char* className() const; + + VM* vm() const; // Extracting the value. JS_EXPORT_PRIVATE bool getString(ExecState*, String&) const; @@ -104,6 +115,12 @@ public: JS_EXPORT_PRIVATE JSObject* getObject(); // NULL if not an object const JSObject* getObject() const; // NULL if not an object + // Returns information about how to call/construct this cell as a function/constructor. May tell + // you that the cell is not callable or constructor (default is that it's not either). If it + // says that the function is callable, and the TypeOfShouldCallGetCallData type flag is set, and + // this is an object, then typeof will return "function" instead of "object". These methods + // cannot change their minds and must be thread-safe. They are sometimes called from compiler + // threads. JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&); JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&); @@ -115,13 +132,19 @@ public: JS_EXPORT_PRIVATE double toNumber(ExecState*) const; JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const; + void dump(PrintStream&) const; + JS_EXPORT_PRIVATE static void dumpToStream(const JSCell*, PrintStream&); + + size_t estimatedSizeInBytes() const; + JS_EXPORT_PRIVATE static size_t estimatedSize(JSCell*); + static void visitChildren(JSCell*, SlotVisitor&); JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken); // Object operations, with the toObject operation included. const ClassInfo* classInfo() const; const MethodTable* methodTable() const; - const MethodTable* methodTableForDestruction() const; + const MethodTable* methodTable(VM&) const; static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); @@ -133,22 +156,41 @@ public: void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; } bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); } - JSValue fastGetOwnProperty(ExecState*, const String&); + static bool canUseFastGetOwnProperty(const Structure&); + JSValue fastGetOwnProperty(VM&, Structure&, PropertyName); - static ptrdiff_t structureOffset() + // The recommended idiom for using cellState() is to switch on it or perform an == comparison on it + // directly. We deliberately avoid helpers for this, because we want transparency about how the various + // CellState values influences our various algorithms. + CellState cellState() const { return m_cellState; } + + void setCellState(CellState data) const { const_cast<JSCell*>(this)->m_cellState = data; } + + static ptrdiff_t structureIDOffset() { - return OBJECT_OFFSETOF(JSCell, m_structure); + return OBJECT_OFFSETOF(JSCell, m_structureID); } - void* structureAddress() + static ptrdiff_t typeInfoFlagsOffset() { - return &m_structure; + return OBJECT_OFFSETOF(JSCell, m_flags); } - -#if ENABLE(GC_VALIDATION) - Structure* unvalidatedStructure() const { return m_structure.unvalidatedGet(); } -#endif - + + static ptrdiff_t typeInfoTypeOffset() + { + return OBJECT_OFFSETOF(JSCell, m_type); + } + + static ptrdiff_t indexingTypeOffset() + { + return OBJECT_OFFSETOF(JSCell, m_indexingType); + } + + static ptrdiff_t cellStateOffset() + { + return OBJECT_OFFSETOF(JSCell, m_cellState); + } + static const TypedArrayType TypedArrayStorageType = NotTypedArray; protected: @@ -160,6 +202,11 @@ protected: static NO_RETURN_DUE_TO_CRASH void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); static NO_RETURN_DUE_TO_CRASH void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); static NO_RETURN_DUE_TO_CRASH void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + + static uint32_t getEnumerableLength(ExecState*, JSObject*); + static NO_RETURN_DUE_TO_CRASH void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + static NO_RETURN_DUE_TO_CRASH void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + static String className(const JSObject*); JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue); static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); @@ -170,34 +217,42 @@ protected: private: friend class LLIntOffsetsExtractor; - - WriteBarrier<Structure> m_structure; + + StructureID m_structureID; + IndexingType m_indexingType; + JSType m_type; + TypeInfo::InlineTypeFlags m_flags; + CellState m_cellState; }; template<typename To, typename From> inline To jsCast(From* from) { - ASSERT(!from || from->JSCell::inherits(std::remove_pointer<To>::type::info())); + ASSERT_WITH_SECURITY_IMPLICATION(!from || from->JSCell::inherits(std::remove_pointer<To>::type::info())); return static_cast<To>(from); } template<typename To> inline To jsCast(JSValue from) { - ASSERT(from.isCell() && from.asCell()->JSCell::inherits(std::remove_pointer<To>::type::info())); + ASSERT_WITH_SECURITY_IMPLICATION(from.isCell() && from.asCell()->JSCell::inherits(std::remove_pointer<To>::type::info())); return static_cast<To>(from.asCell()); } template<typename To, typename From> inline To jsDynamicCast(From* from) { - return from->inherits(std::remove_pointer<To>::type::info()) ? static_cast<To>(from) : 0; + if (LIKELY(from->inherits(std::remove_pointer<To>::type::info()))) + return static_cast<To>(from); + return nullptr; } template<typename To> inline To jsDynamicCast(JSValue from) { - return from.isCell() && from.asCell()->inherits(std::remove_pointer<To>::type::info()) ? static_cast<To>(from.asCell()) : 0; + if (LIKELY(from.isCell() && from.asCell()->inherits(std::remove_pointer<To>::type::info()))) + return static_cast<To>(from.asCell()); + return nullptr; } } // namespace JSC |
