Reduce JSC API static value setter/getter overhead.
[WebKit-https.git] / Source / JavaScriptCore / API / JSClassRef.h
1 /*
2  * Copyright (C) 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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), setProperty(_setProperty), attributes(_attributes), propertyNameRef(OpaqueJSString::create(propertyName))
41     {
42     }
43     
44     JSObjectGetPropertyCallback getProperty;
45     JSObjectSetPropertyCallback setProperty;
46     JSPropertyAttributes attributes;
47     RefPtr<OpaqueJSString> propertyNameRef;
48 };
49
50 struct StaticFunctionEntry {
51     WTF_MAKE_FAST_ALLOCATED;
52 public:
53     StaticFunctionEntry(JSObjectCallAsFunctionCallback _callAsFunction, JSPropertyAttributes _attributes)
54         : callAsFunction(_callAsFunction), attributes(_attributes)
55     {
56     }
57
58     JSObjectCallAsFunctionCallback callAsFunction;
59     JSPropertyAttributes attributes;
60 };
61
62 typedef HashMap<RefPtr<StringImpl>, OwnPtr<StaticValueEntry> > OpaqueJSClassStaticValuesTable;
63 typedef HashMap<RefPtr<StringImpl>, OwnPtr<StaticFunctionEntry> > OpaqueJSClassStaticFunctionsTable;
64
65 struct OpaqueJSClass;
66
67 // An OpaqueJSClass (JSClass) is created without a context, so it can be used with any context, even across context groups.
68 // This structure holds data members that vary across context groups.
69 struct OpaqueJSClassContextData {
70     WTF_MAKE_NONCOPYABLE(OpaqueJSClassContextData); WTF_MAKE_FAST_ALLOCATED;
71 public:
72     OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass*);
73
74     // It is necessary to keep OpaqueJSClass alive because of the following rare scenario:
75     // 1. A class is created and used, so its context data is stored in VM hash map.
76     // 2. The class is released, and when all JS objects that use it are collected, OpaqueJSClass
77     // is deleted (that's the part prevented by this RefPtr).
78     // 3. Another class is created at the same address.
79     // 4. When it is used, the old context data is found in VM and used.
80     RefPtr<OpaqueJSClass> m_class;
81
82     OwnPtr<OpaqueJSClassStaticValuesTable> staticValues;
83     OwnPtr<OpaqueJSClassStaticFunctionsTable> staticFunctions;
84     JSC::Weak<JSC::JSObject> cachedPrototype;
85 };
86
87 struct OpaqueJSClass : public ThreadSafeRefCounted<OpaqueJSClass> {
88     static PassRefPtr<OpaqueJSClass> create(const JSClassDefinition*);
89     static PassRefPtr<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
90     JS_EXPORT_PRIVATE ~OpaqueJSClass();
91     
92     String className();
93     OpaqueJSClassStaticValuesTable* staticValues(JSC::ExecState*);
94     OpaqueJSClassStaticFunctionsTable* staticFunctions(JSC::ExecState*);
95     JSC::JSObject* prototype(JSC::ExecState*);
96
97     OpaqueJSClass* parentClass;
98     OpaqueJSClass* prototypeClass;
99     
100     JSObjectInitializeCallback initialize;
101     JSObjectFinalizeCallback finalize;
102     JSObjectHasPropertyCallback hasProperty;
103     JSObjectGetPropertyCallback getProperty;
104     JSObjectSetPropertyCallback setProperty;
105     JSObjectDeletePropertyCallback deleteProperty;
106     JSObjectGetPropertyNamesCallback getPropertyNames;
107     JSObjectCallAsFunctionCallback callAsFunction;
108     JSObjectCallAsConstructorCallback callAsConstructor;
109     JSObjectHasInstanceCallback hasInstance;
110     JSObjectConvertToTypeCallback convertToType;
111
112 private:
113     friend struct OpaqueJSClassContextData;
114
115     OpaqueJSClass();
116     OpaqueJSClass(const OpaqueJSClass&);
117     OpaqueJSClass(const JSClassDefinition*, OpaqueJSClass* protoClass);
118
119     OpaqueJSClassContextData& contextData(JSC::ExecState*);
120
121     // Strings in these data members should not be put into any IdentifierTable.
122     String m_className;
123     OwnPtr<OpaqueJSClassStaticValuesTable> m_staticValues;
124     OwnPtr<OpaqueJSClassStaticFunctionsTable> m_staticFunctions;
125 };
126
127 #endif // JSClassRef_h