90c4f539005c82b0e23ab91207699aea4a039a89
[WebKit.git] / Source / JavaScriptCore / API / JSClassRef.h
1 /*
2  * Copyright (C) 2006 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef JSClassRef_h
27 #define JSClassRef_h
28
29 #include "OpaqueJSString.h"
30 #include "Protect.h"
31 #include "Weak.h"
32 #include <JavaScriptCore/JSObjectRef.h>
33 #include <wtf/HashMap.h>
34 #include <wtf/text/WTFString.h>
35
36 struct StaticValueEntry {
37     WTF_MAKE_FAST_ALLOCATED;
38 public:
39     StaticValueEntry(JSObjectGetPropertyCallback _getProperty, JSObjectSetPropertyCallback _setProperty, JSPropertyAttributes _attributes, String& propertyName)
40         : getProperty(_getProperty)
41         , setProperty(_setProperty)
42         , attributes(_attributes)
43         , propertyNameRef(OpaqueJSString::tryCreate(propertyName))
44     {
45     }
46     
47     JSObjectGetPropertyCallback getProperty;
48     JSObjectSetPropertyCallback setProperty;
49     JSPropertyAttributes attributes;
50     RefPtr<OpaqueJSString> propertyNameRef;
51 };
52
53 struct StaticFunctionEntry {
54     WTF_MAKE_FAST_ALLOCATED;
55 public:
56     StaticFunctionEntry(JSObjectCallAsFunctionCallback _callAsFunction, JSPropertyAttributes _attributes)
57         : callAsFunction(_callAsFunction), attributes(_attributes)
58     {
59     }
60
61     JSObjectCallAsFunctionCallback callAsFunction;
62     JSPropertyAttributes attributes;
63 };
64
65 typedef HashMap<RefPtr<StringImpl>, std::unique_ptr<StaticValueEntry>> OpaqueJSClassStaticValuesTable;
66 typedef HashMap<RefPtr<StringImpl>, std::unique_ptr<StaticFunctionEntry>> OpaqueJSClassStaticFunctionsTable;
67
68 struct OpaqueJSClass;
69
70 // An OpaqueJSClass (JSClass) is created without a context, so it can be used with any context, even across context groups.
71 // This structure holds data members that vary across context groups.
72 struct OpaqueJSClassContextData {
73     WTF_MAKE_NONCOPYABLE(OpaqueJSClassContextData); WTF_MAKE_FAST_ALLOCATED;
74 public:
75     OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass*);
76
77     // It is necessary to keep OpaqueJSClass alive because of the following rare scenario:
78     // 1. A class is created and used, so its context data is stored in VM hash map.
79     // 2. The class is released, and when all JS objects that use it are collected, OpaqueJSClass
80     // is deleted (that's the part prevented by this RefPtr).
81     // 3. Another class is created at the same address.
82     // 4. When it is used, the old context data is found in VM and used.
83     RefPtr<OpaqueJSClass> m_class;
84
85     std::unique_ptr<OpaqueJSClassStaticValuesTable> staticValues;
86     std::unique_ptr<OpaqueJSClassStaticFunctionsTable> staticFunctions;
87     JSC::Weak<JSC::JSObject> cachedPrototype;
88 };
89
90 struct OpaqueJSClass : public ThreadSafeRefCounted<OpaqueJSClass> {
91     static Ref<OpaqueJSClass> create(const JSClassDefinition*);
92     static Ref<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
93     JS_EXPORT_PRIVATE ~OpaqueJSClass();
94     
95     String className();
96     OpaqueJSClassStaticValuesTable* staticValues(JSC::ExecState*);
97     OpaqueJSClassStaticFunctionsTable* staticFunctions(JSC::ExecState*);
98     JSC::JSObject* prototype(JSC::ExecState*);
99
100     OpaqueJSClass* parentClass;
101     OpaqueJSClass* prototypeClass;
102     
103     JSObjectInitializeCallback initialize;
104     JSObjectFinalizeCallback finalize;
105     JSObjectHasPropertyCallback hasProperty;
106     JSObjectGetPropertyCallback getProperty;
107     JSObjectSetPropertyCallback setProperty;
108     JSObjectDeletePropertyCallback deleteProperty;
109     JSObjectGetPropertyNamesCallback getPropertyNames;
110     JSObjectCallAsFunctionCallback callAsFunction;
111     JSObjectCallAsConstructorCallback callAsConstructor;
112     JSObjectHasInstanceCallback hasInstance;
113     JSObjectConvertToTypeCallback convertToType;
114
115 private:
116     friend struct OpaqueJSClassContextData;
117
118     OpaqueJSClass();
119     OpaqueJSClass(const OpaqueJSClass&);
120     OpaqueJSClass(const JSClassDefinition*, OpaqueJSClass* protoClass);
121
122     OpaqueJSClassContextData& contextData(JSC::ExecState*);
123
124     // Strings in these data members should not be put into any AtomicStringTable.
125     String m_className;
126     std::unique_ptr<OpaqueJSClassStaticValuesTable> m_staticValues;
127     std::unique_ptr<OpaqueJSClassStaticFunctionsTable> m_staticFunctions;
128 };
129
130 #endif // JSClassRef_h