JSCallbackObject.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
  3. * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
  18. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  19. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  21. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  22. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #ifndef JSCallbackObject_h
  27. #define JSCallbackObject_h
  28. #include "JSObjectRef.h"
  29. #include "JSValueRef.h"
  30. #include "JSObject.h"
  31. #include <wtf/PassOwnPtr.h>
  32. namespace JSC {
  33. struct JSCallbackObjectData : WeakHandleOwner {
  34. JSCallbackObjectData(void* privateData, JSClassRef jsClass)
  35. : privateData(privateData)
  36. , jsClass(jsClass)
  37. {
  38. JSClassRetain(jsClass);
  39. }
  40. ~JSCallbackObjectData()
  41. {
  42. JSClassRelease(jsClass);
  43. }
  44. JSValue getPrivateProperty(const Identifier& propertyName) const
  45. {
  46. if (!m_privateProperties)
  47. return JSValue();
  48. return m_privateProperties->getPrivateProperty(propertyName);
  49. }
  50. void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
  51. {
  52. if (!m_privateProperties)
  53. m_privateProperties = adoptPtr(new JSPrivatePropertyMap);
  54. m_privateProperties->setPrivateProperty(vm, owner, propertyName, value);
  55. }
  56. void deletePrivateProperty(const Identifier& propertyName)
  57. {
  58. if (!m_privateProperties)
  59. return;
  60. m_privateProperties->deletePrivateProperty(propertyName);
  61. }
  62. void visitChildren(SlotVisitor& visitor)
  63. {
  64. if (!m_privateProperties)
  65. return;
  66. m_privateProperties->visitChildren(visitor);
  67. }
  68. void* privateData;
  69. JSClassRef jsClass;
  70. struct JSPrivatePropertyMap {
  71. JSValue getPrivateProperty(const Identifier& propertyName) const
  72. {
  73. PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.impl());
  74. if (location == m_propertyMap.end())
  75. return JSValue();
  76. return location->value.get();
  77. }
  78. void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
  79. {
  80. WriteBarrier<Unknown> empty;
  81. m_propertyMap.add(propertyName.impl(), empty).iterator->value.set(vm, owner, value);
  82. }
  83. void deletePrivateProperty(const Identifier& propertyName)
  84. {
  85. m_propertyMap.remove(propertyName.impl());
  86. }
  87. void visitChildren(SlotVisitor& visitor)
  88. {
  89. for (PrivatePropertyMap::iterator ptr = m_propertyMap.begin(); ptr != m_propertyMap.end(); ++ptr) {
  90. if (ptr->value)
  91. visitor.append(&ptr->value);
  92. }
  93. }
  94. private:
  95. typedef HashMap<RefPtr<StringImpl>, WriteBarrier<Unknown>, IdentifierRepHash> PrivatePropertyMap;
  96. PrivatePropertyMap m_propertyMap;
  97. };
  98. OwnPtr<JSPrivatePropertyMap> m_privateProperties;
  99. virtual void finalize(Handle<Unknown>, void*);
  100. };
  101. template <class Parent>
  102. class JSCallbackObject : public Parent {
  103. protected:
  104. JSCallbackObject(ExecState*, Structure*, JSClassRef, void* data);
  105. JSCallbackObject(VM&, JSClassRef, Structure*);
  106. void finishCreation(ExecState*);
  107. void finishCreation(VM&);
  108. public:
  109. typedef Parent Base;
  110. static JSCallbackObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, void* data)
  111. {
  112. ASSERT_UNUSED(globalObject, !structure->globalObject() || structure->globalObject() == globalObject);
  113. JSCallbackObject* callbackObject = new (NotNull, allocateCell<JSCallbackObject>(*exec->heap())) JSCallbackObject(exec, structure, classRef, data);
  114. callbackObject->finishCreation(exec);
  115. return callbackObject;
  116. }
  117. static JSCallbackObject<Parent>* create(VM&, JSClassRef, Structure*);
  118. static const bool needsDestruction;
  119. static void destroy(JSCell* cell)
  120. {
  121. static_cast<JSCallbackObject*>(cell)->JSCallbackObject::~JSCallbackObject();
  122. }
  123. void setPrivate(void* data);
  124. void* getPrivate();
  125. static const ClassInfo s_info;
  126. JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
  127. bool inherits(JSClassRef) const;
  128. static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
  129. JSValue getPrivateProperty(const Identifier& propertyName) const
  130. {
  131. return m_callbackObjectData->getPrivateProperty(propertyName);
  132. }
  133. void setPrivateProperty(VM& vm, const Identifier& propertyName, JSValue value)
  134. {
  135. m_callbackObjectData->setPrivateProperty(vm, this, propertyName, value);
  136. }
  137. void deletePrivateProperty(const Identifier& propertyName)
  138. {
  139. m_callbackObjectData->deletePrivateProperty(propertyName);
  140. }
  141. using Parent::methodTable;
  142. protected:
  143. static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags;
  144. private:
  145. static String className(const JSObject*);
  146. static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
  147. static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
  148. static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
  149. static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
  150. static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
  151. static void putByIndex(JSCell*, ExecState*, unsigned, JSValue, bool shouldThrow);
  152. static bool deleteProperty(JSCell*, ExecState*, PropertyName);
  153. static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
  154. static bool customHasInstance(JSObject*, ExecState*, JSValue);
  155. static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
  156. static ConstructType getConstructData(JSCell*, ConstructData&);
  157. static CallType getCallData(JSCell*, CallData&);
  158. static void visitChildren(JSCell* cell, SlotVisitor& visitor)
  159. {
  160. JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
  161. ASSERT_GC_OBJECT_INHERITS((static_cast<Parent*>(thisObject)), &JSCallbackObject<Parent>::s_info);
  162. COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
  163. ASSERT(thisObject->Parent::structure()->typeInfo().overridesVisitChildren());
  164. Parent::visitChildren(thisObject, visitor);
  165. thisObject->m_callbackObjectData->visitChildren(visitor);
  166. }
  167. void init(ExecState*);
  168. static JSCallbackObject* asCallbackObject(JSValue);
  169. static EncodedJSValue JSC_HOST_CALL call(ExecState*);
  170. static EncodedJSValue JSC_HOST_CALL construct(ExecState*);
  171. JSValue getStaticValue(ExecState*, PropertyName);
  172. static JSValue staticFunctionGetter(ExecState*, JSValue, PropertyName);
  173. static JSValue callbackGetter(ExecState*, JSValue, PropertyName);
  174. OwnPtr<JSCallbackObjectData> m_callbackObjectData;
  175. };
  176. } // namespace JSC
  177. // include the actual template class implementation
  178. #include "JSCallbackObjectFunctions.h"
  179. #endif // JSCallbackObject_h