tizen beta release
[framework/web/webkit-efl.git] / Source / JavaScriptCore / API / JSCallbackObject.h
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
27 #ifndef JSCallbackObject_h
28 #define JSCallbackObject_h
29
30 #include "JSObjectRef.h"
31 #include "JSValueRef.h"
32 #include "JSObject.h"
33 #include <wtf/PassOwnPtr.h>
34
35 namespace JSC {
36
37 struct JSCallbackObjectData : WeakHandleOwner {
38     JSCallbackObjectData(void* privateData, JSClassRef jsClass)
39         : privateData(privateData)
40         , jsClass(jsClass)
41     {
42         JSClassRetain(jsClass);
43     }
44     
45     ~JSCallbackObjectData()
46     {
47         JSClassRelease(jsClass);
48     }
49     
50     JSValue getPrivateProperty(const Identifier& propertyName) const
51     {
52         if (!m_privateProperties)
53             return JSValue();
54         return m_privateProperties->getPrivateProperty(propertyName);
55     }
56     
57     void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value)
58     {
59         if (!m_privateProperties)
60             m_privateProperties = adoptPtr(new JSPrivatePropertyMap);
61         m_privateProperties->setPrivateProperty(globalData, owner, propertyName, value);
62     }
63     
64     void deletePrivateProperty(const Identifier& propertyName)
65     {
66         if (!m_privateProperties)
67             return;
68         m_privateProperties->deletePrivateProperty(propertyName);
69     }
70
71     void visitChildren(SlotVisitor& visitor)
72     {
73         if (!m_privateProperties)
74             return;
75         m_privateProperties->visitChildren(visitor);
76     }
77
78     void* privateData;
79     JSClassRef jsClass;
80     struct JSPrivatePropertyMap {
81         JSValue getPrivateProperty(const Identifier& propertyName) const
82         {
83             PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.impl());
84             if (location == m_propertyMap.end())
85                 return JSValue();
86             return location->second.get();
87         }
88         
89         void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value)
90         {
91             WriteBarrier<Unknown> empty;
92             m_propertyMap.add(propertyName.impl(), empty).first->second.set(globalData, owner, value);
93         }
94         
95         void deletePrivateProperty(const Identifier& propertyName)
96         {
97             m_propertyMap.remove(propertyName.impl());
98         }
99
100         void visitChildren(SlotVisitor& visitor)
101         {
102             for (PrivatePropertyMap::iterator ptr = m_propertyMap.begin(); ptr != m_propertyMap.end(); ++ptr) {
103                 if (ptr->second)
104                     visitor.append(&ptr->second);
105             }
106         }
107
108     private:
109         typedef HashMap<RefPtr<StringImpl>, WriteBarrier<Unknown>, IdentifierRepHash> PrivatePropertyMap;
110         PrivatePropertyMap m_propertyMap;
111     };
112     OwnPtr<JSPrivatePropertyMap> m_privateProperties;
113     virtual void finalize(Handle<Unknown>, void*);
114 };
115
116     
117 template <class Parent>
118 class JSCallbackObject : public Parent {
119 protected:
120     JSCallbackObject(ExecState*, Structure*, JSClassRef, void* data);
121     JSCallbackObject(JSGlobalData&, JSClassRef, Structure*);
122     // We'd like to use the placement version of operator new defined in JSCell, but 
123     // we can't because Parent is a template argument, so we just duplicate the same 
124     // functionality here.
125     void* operator new(size_t, void* ptr) { return ptr; }
126
127     void finishCreation(ExecState*);
128     void finishCreation(JSGlobalData&);
129
130 public:
131     typedef Parent Base;
132
133     static JSCallbackObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, void* data)
134     {
135         ASSERT_UNUSED(globalObject, !structure->globalObject() || structure->globalObject() == globalObject);
136         JSCallbackObject* callbackObject = new (allocateCell<JSCallbackObject>(*exec->heap())) JSCallbackObject(exec, structure, classRef, data);
137         callbackObject->finishCreation(exec);
138         return callbackObject;
139     }
140     static JSCallbackObject* create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure)
141     {
142         JSCallbackObject* callbackObject = new (allocateCell<JSCallbackObject>(globalData.heap)) JSCallbackObject(globalData, classRef, structure);
143         callbackObject->finishCreation(globalData);
144         return callbackObject;
145     }
146
147     void setPrivate(void* data);
148     void* getPrivate();
149
150     static const ClassInfo s_info;
151
152     JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
153     bool inherits(JSClassRef) const;
154
155     static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue);
156     
157     JSValue getPrivateProperty(const Identifier& propertyName) const
158     {
159         return m_callbackObjectData->getPrivateProperty(propertyName);
160     }
161     
162     void setPrivateProperty(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
163     {
164         m_callbackObjectData->setPrivateProperty(globalData, this, propertyName, value);
165     }
166     
167     void deletePrivateProperty(const Identifier& propertyName)
168     {
169         m_callbackObjectData->deletePrivateProperty(propertyName);
170     }
171
172     using Parent::methodTable;
173
174 protected:
175     static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags;
176
177 private:
178     static UString className(const JSObject*);
179
180     static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
181     static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
182     
183     static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&);
184
185     static bool deleteProperty(JSCell*, ExecState*, const Identifier&);
186     static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
187
188     static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);
189
190     static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
191
192     static ConstructType getConstructData(JSCell*, ConstructData&);
193     static CallType getCallData(JSCell*, CallData&);
194
195     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
196     {
197         JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
198         ASSERT_GC_OBJECT_INHERITS((static_cast<Parent*>(thisObject)), &JSCallbackObject<Parent>::s_info);
199         COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
200         ASSERT(thisObject->Parent::structure()->typeInfo().overridesVisitChildren());
201         Parent::visitChildren(thisObject, visitor);
202         thisObject->m_callbackObjectData->visitChildren(visitor);
203     }
204
205     void init(ExecState*);
206  
207     static JSCallbackObject* asCallbackObject(JSValue);
208  
209     static EncodedJSValue JSC_HOST_CALL call(ExecState*);
210     static EncodedJSValue JSC_HOST_CALL construct(ExecState*);
211    
212     JSValue getStaticValue(ExecState*, const Identifier&);
213     static JSValue staticFunctionGetter(ExecState*, JSValue, const Identifier&);
214     static JSValue callbackGetter(ExecState*, JSValue, const Identifier&);
215
216     OwnPtr<JSCallbackObjectData> m_callbackObjectData;
217 };
218
219 } // namespace JSC
220
221 // include the actual template class implementation
222 #include "JSCallbackObjectFunctions.h"
223
224 #endif // JSCallbackObject_h