JSCell.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  3. * Copyright (C) 2001 Peter Kelly (pmk@post.com)
  4. * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Library General Public License
  17. * along with this library; see the file COPYING.LIB. If not, write to
  18. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. * Boston, MA 02110-1301, USA.
  20. *
  21. */
  22. #ifndef JSCell_h
  23. #define JSCell_h
  24. #include "CallData.h"
  25. #include "ConstructData.h"
  26. #include "Heap.h"
  27. #include "JSLock.h"
  28. #include "SlotVisitor.h"
  29. #include "TypedArrayDescriptor.h"
  30. #include "WriteBarrier.h"
  31. #include <wtf/Noncopyable.h>
  32. #include <wtf/TypeTraits.h>
  33. namespace JSC {
  34. class CopyVisitor;
  35. class ExecState;
  36. class JSDestructibleObject;
  37. class JSGlobalObject;
  38. class LLIntOffsetsExtractor;
  39. class PropertyDescriptor;
  40. class PropertyNameArray;
  41. class Structure;
  42. enum EnumerationMode {
  43. ExcludeDontEnumProperties,
  44. IncludeDontEnumProperties
  45. };
  46. template<typename T> void* allocateCell(Heap&);
  47. template<typename T> void* allocateCell(Heap&, size_t);
  48. class JSCell {
  49. friend class JSValue;
  50. friend class MarkedBlock;
  51. template<typename T> friend void* allocateCell(Heap&);
  52. template<typename T> friend void* allocateCell(Heap&, size_t);
  53. public:
  54. static const unsigned StructureFlags = 0;
  55. static const bool needsDestruction = false;
  56. static const bool hasImmortalStructure = false;
  57. enum CreatingEarlyCellTag { CreatingEarlyCell };
  58. JSCell(CreatingEarlyCellTag);
  59. protected:
  60. JSCell(VM&, Structure*);
  61. JS_EXPORT_PRIVATE static void destroy(JSCell*);
  62. public:
  63. // Querying the type.
  64. bool isString() const;
  65. bool isObject() const;
  66. bool isGetterSetter() const;
  67. bool isProxy() const;
  68. bool inherits(const ClassInfo*) const;
  69. bool isAPIValueWrapper() const;
  70. Structure* structure() const;
  71. void setStructure(VM&, Structure*);
  72. void clearStructure() { m_structure.clear(); }
  73. const char* className();
  74. // Extracting the value.
  75. JS_EXPORT_PRIVATE bool getString(ExecState*, String&) const;
  76. JS_EXPORT_PRIVATE String getString(ExecState*) const; // null string if not a string
  77. JS_EXPORT_PRIVATE JSObject* getObject(); // NULL if not an object
  78. const JSObject* getObject() const; // NULL if not an object
  79. JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&);
  80. JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&);
  81. // Basic conversions.
  82. JS_EXPORT_PRIVATE JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
  83. bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
  84. bool toBoolean(ExecState*) const;
  85. TriState pureToBoolean() const;
  86. JS_EXPORT_PRIVATE double toNumber(ExecState*) const;
  87. JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const;
  88. static void visitChildren(JSCell*, SlotVisitor&);
  89. JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&);
  90. // Object operations, with the toObject operation included.
  91. const ClassInfo* classInfo() const;
  92. const MethodTable* methodTable() const;
  93. const MethodTable* methodTableForDestruction() const;
  94. static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
  95. static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
  96. static bool deleteProperty(JSCell*, ExecState*, PropertyName);
  97. static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
  98. static JSObject* toThisObject(JSCell*, ExecState*);
  99. void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; }
  100. bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); }
  101. // FIXME: Rename getOwnPropertySlot to virtualGetOwnPropertySlot, and
  102. // fastGetOwnPropertySlot to getOwnPropertySlot. Callers should always
  103. // call this function, not its slower virtual counterpart. (For integer
  104. // property names, we want a similar interface with appropriate optimizations.)
  105. bool fastGetOwnPropertySlot(ExecState*, PropertyName, PropertySlot&);
  106. JSValue fastGetOwnProperty(ExecState*, const String&);
  107. static ptrdiff_t structureOffset()
  108. {
  109. return OBJECT_OFFSETOF(JSCell, m_structure);
  110. }
  111. void* structureAddress()
  112. {
  113. return &m_structure;
  114. }
  115. #if ENABLE(GC_VALIDATION)
  116. Structure* unvalidatedStructure() { return m_structure.unvalidatedGet(); }
  117. #endif
  118. static const TypedArrayType TypedArrayStorageType = TypedArrayNone;
  119. protected:
  120. void finishCreation(VM&);
  121. void finishCreation(VM&, Structure*, CreatingEarlyCellTag);
  122. // Base implementation; for non-object classes implements getPropertySlot.
  123. static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
  124. static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
  125. // Dummy implementations of override-able static functions for classes to put in their MethodTable
  126. static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
  127. static NO_RETURN_DUE_TO_CRASH void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
  128. static NO_RETURN_DUE_TO_CRASH void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
  129. static NO_RETURN_DUE_TO_CRASH void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
  130. static String className(const JSObject*);
  131. JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue);
  132. static NO_RETURN_DUE_TO_CRASH void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
  133. static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
  134. static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
  135. private:
  136. friend class LLIntOffsetsExtractor;
  137. WriteBarrier<Structure> m_structure;
  138. };
  139. template<typename To, typename From>
  140. inline To jsCast(From* from)
  141. {
  142. #if !(ENABLE(DETACHED_JIT) && BUILDING_DETACHED_JIT)
  143. ASSERT(!from || from->JSCell::inherits(&WTF::RemovePointer<To>::Type::s_info));
  144. #endif
  145. return static_cast<To>(from);
  146. }
  147. template<typename To>
  148. inline To jsCast(JSValue from)
  149. {
  150. #if !(ENABLE(DETACHED_JIT) && BUILDING_DETACHED_JIT)
  151. ASSERT(from.isCell() && from.asCell()->JSCell::inherits(&WTF::RemovePointer<To>::Type::s_info));
  152. #endif
  153. return static_cast<To>(from.asCell());
  154. }
  155. template<typename To, typename From>
  156. inline To jsDynamicCast(From* from)
  157. {
  158. return from->inherits(&WTF::RemovePointer<To>::Type::s_info) ? static_cast<To>(from) : 0;
  159. }
  160. template<typename To>
  161. inline To jsDynamicCast(JSValue from)
  162. {
  163. return from.isCell() && from.asCell()->inherits(&WTF::RemovePointer<To>::Type::s_info) ? static_cast<To>(from.asCell()) : 0;
  164. }
  165. } // namespace JSC
  166. #endif // JSCell_h