summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSCell.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSCell.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h146
1 files changed, 103 insertions, 43 deletions
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index 04bf4b420..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,19 +24,24 @@
#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 "TypedArrayDescriptor.h"
+#include "TypedArrayType.h"
#include "WriteBarrier.h"
#include <wtf/Noncopyable.h>
-#include <wtf/TypeTraits.h>
namespace JSC {
class CopyVisitor;
class ExecState;
+class Identifier;
+class JSArrayBufferView;
class JSDestructibleObject;
class JSGlobalObject;
class LLIntOffsetsExtractor;
@@ -44,14 +49,21 @@ class PropertyDescriptor;
class PropertyNameArray;
class Structure;
-enum EnumerationMode {
- ExcludeDontEnumProperties,
- IncludeDontEnumProperties
-};
-
template<typename T> void* allocateCell(Heap&);
template<typename T> void* allocateCell(Heap&, size_t);
+#define DECLARE_EXPORT_INFO \
+ protected: \
+ static JS_EXPORTDATA const ::JSC::ClassInfo s_info; \
+ public: \
+ static const ::JSC::ClassInfo* info() { return &s_info; }
+
+#define DECLARE_INFO \
+ protected: \
+ static const ::JSC::ClassInfo s_info; \
+ public: \
+ static const ::JSC::ClassInfo* info() { return &s_info; }
+
class JSCell {
friend class JSValue;
friend class MarkedBlock;
@@ -62,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);
@@ -74,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;
- const char* className();
+ VM* vm() const;
// Extracting the value.
JS_EXPORT_PRIVATE bool getString(ExecState*, String&) const;
@@ -92,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&);
@@ -103,96 +132,127 @@ 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&);
+ 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);
static bool deleteProperty(JSCell*, ExecState*, PropertyName);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
- static JSObject* toThisObject(JSCell*, ExecState*);
+ static JSValue toThis(JSCell*, ExecState*, ECMAMode);
void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
- // FIXME: Rename getOwnPropertySlot to virtualGetOwnPropertySlot, and
- // fastGetOwnPropertySlot to getOwnPropertySlot. Callers should always
- // call this function, not its slower virtual counterpart. (For integer
- // property names, we want a similar interface with appropriate optimizations.)
- bool fastGetOwnPropertySlot(ExecState*, PropertyName, PropertySlot&);
- JSValue fastGetOwnProperty(ExecState*, const String&);
+ static bool canUseFastGetOwnProperty(const Structure&);
+ JSValue fastGetOwnProperty(VM&, Structure&, PropertyName);
+
+ // 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 structureOffset()
+ 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() { return m_structure.unvalidatedGet(); }
-#endif
-
- static const TypedArrayType TypedArrayStorageType = TypedArrayNone;
+
+ 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:
void finishCreation(VM&);
void finishCreation(VM&, Structure*, CreatingEarlyCellTag);
- // Base implementation; for non-object classes implements getPropertySlot.
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
-
// Dummy implementations of override-able static functions for classes to put in their MethodTable
static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
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 NO_RETURN_DUE_TO_CRASH void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
- static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+ static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+ static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
+ JS_EXPORT_PRIVATE static ArrayBuffer* slowDownAndWasteMemory(JSArrayBufferView*);
+ JS_EXPORT_PRIVATE static PassRefPtr<ArrayBufferView> getTypedArrayImpl(JSArrayBufferView*);
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(&WTF::RemovePointer<To>::Type::s_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(&WTF::RemovePointer<To>::Type::s_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(&WTF::RemovePointer<To>::Type::s_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(&WTF::RemovePointer<To>::Type::s_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