Bumping manifests a=b2g-bump
[gecko.git] / dom / bindings / DOMJSClass.h
bloba2deffc44bcbbc585a34b2dd922c3eb2d9132133
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_dom_DOMJSClass_h
7 #define mozilla_dom_DOMJSClass_h
9 #include "jsfriendapi.h"
10 #include "mozilla/Assertions.h"
12 #include "mozilla/dom/PrototypeList.h" // auto-generated
14 #include "mozilla/dom/JSSlots.h"
16 class nsCycleCollectionParticipant;
18 // All DOM globals must have a slot at DOM_PROTOTYPE_SLOT.
19 #define DOM_PROTOTYPE_SLOT JSCLASS_GLOBAL_SLOT_COUNT
21 // Keep this count up to date with any extra global slots added above.
22 #define DOM_GLOBAL_SLOTS 1
24 // We use these flag bits for the new bindings.
25 #define JSCLASS_DOM_GLOBAL JSCLASS_USERBIT1
26 #define JSCLASS_IS_DOMIFACEANDPROTOJSCLASS JSCLASS_USERBIT2
28 namespace mozilla {
29 namespace dom {
31 typedef bool
32 (* ResolveOwnProperty)(JSContext* cx, JS::Handle<JSObject*> wrapper,
33 JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
34 JS::MutableHandle<JSPropertyDescriptor> desc);
36 typedef bool
37 (* EnumerateOwnProperties)(JSContext* cx, JS::Handle<JSObject*> wrapper,
38 JS::Handle<JSObject*> obj,
39 JS::AutoIdVector& props);
41 bool
42 CheckPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
44 struct ConstantSpec
46 const char* name;
47 JS::Value value;
50 typedef bool (*PropertyEnabled)(JSContext* cx, JSObject* global);
52 template<typename T>
53 struct Prefable {
54 inline bool isEnabled(JSContext* cx, JSObject* obj) const {
55 if (!enabled) {
56 return false;
58 if (!enabledFunc && !availableFunc && !checkPermissions) {
59 return true;
61 // Just go ahead and root obj, in case enabledFunc GCs
62 JS::Rooted<JSObject*> rootedObj(cx, obj);
63 if (enabledFunc &&
64 !enabledFunc(cx, js::GetGlobalForObjectCrossCompartment(rootedObj))) {
65 return false;
67 if (availableFunc &&
68 !availableFunc(cx, js::GetGlobalForObjectCrossCompartment(rootedObj))) {
69 return false;
71 if (checkPermissions &&
72 !CheckPermissions(cx, js::GetGlobalForObjectCrossCompartment(rootedObj),
73 checkPermissions)) {
74 return false;
76 return true;
79 // A boolean indicating whether this set of specs is enabled
80 bool enabled;
81 // A function pointer to a function that can say the property is disabled
82 // even if "enabled" is set to true. If the pointer is null the value of
83 // "enabled" is used as-is unless availableFunc overrides.
84 PropertyEnabled enabledFunc;
85 // A function pointer to a function that can be used to disable a
86 // property even if "enabled" is true and enabledFunc allowed. This
87 // is basically a hack to avoid having to codegen PropertyEnabled
88 // implementations in case when we need to do two separate checks.
89 PropertyEnabled availableFunc;
90 const char* const* checkPermissions;
91 // Array of specs, terminated in whatever way is customary for T.
92 // Null to indicate a end-of-array for Prefable, when such an
93 // indicator is needed.
94 const T* specs;
97 struct NativeProperties
99 const Prefable<const JSFunctionSpec>* staticMethods;
100 jsid* staticMethodIds;
101 const JSFunctionSpec* staticMethodSpecs;
103 const Prefable<const JSPropertySpec>* staticAttributes;
104 jsid* staticAttributeIds;
105 const JSPropertySpec* staticAttributeSpecs;
107 const Prefable<const JSFunctionSpec>* methods;
108 jsid* methodIds;
109 const JSFunctionSpec* methodSpecs;
111 const Prefable<const JSPropertySpec>* attributes;
112 jsid* attributeIds;
113 const JSPropertySpec* attributeSpecs;
115 const Prefable<const JSFunctionSpec>* unforgeableMethods;
116 jsid* unforgeableMethodIds;
117 const JSFunctionSpec* unforgeableMethodSpecs;
119 const Prefable<const JSPropertySpec>* unforgeableAttributes;
120 jsid* unforgeableAttributeIds;
121 const JSPropertySpec* unforgeableAttributeSpecs;
123 const Prefable<const ConstantSpec>* constants;
124 jsid* constantIds;
125 const ConstantSpec* constantSpecs;
128 struct NativePropertiesHolder
130 const NativeProperties* regular;
131 const NativeProperties* chromeOnly;
134 // Helper structure for Xrays for DOM binding objects. The same instance is used
135 // for instances, interface objects and interface prototype objects of a
136 // specific interface.
137 struct NativePropertyHooks
139 // The hook to call for resolving indexed or named properties. May be null if
140 // there can't be any.
141 ResolveOwnProperty mResolveOwnProperty;
142 // The hook to call for enumerating indexed or named properties. May be null
143 // if there can't be any.
144 EnumerateOwnProperties mEnumerateOwnProperties;
146 // The property arrays for this interface.
147 NativePropertiesHolder mNativeProperties;
149 // This will be set to the ID of the interface prototype object for the
150 // interface, if it has one. If it doesn't have one it will be set to
151 // prototypes::id::_ID_Count.
152 prototypes::ID mPrototypeID;
154 // This will be set to the ID of the interface object for the interface, if it
155 // has one. If it doesn't have one it will be set to
156 // constructors::id::_ID_Count.
157 constructors::ID mConstructorID;
159 // The NativePropertyHooks instance for the parent interface (for
160 // ShimInterfaceInfo).
161 const NativePropertyHooks* mProtoHooks;
164 enum DOMObjectType {
165 eInstance,
166 eGlobalInstance,
167 eInterface,
168 eInterfacePrototype,
169 eGlobalInterfacePrototype,
170 eNamedPropertiesObject
173 inline
174 bool
175 IsInstance(DOMObjectType type)
177 return type == eInstance || type == eGlobalInstance;
180 inline
181 bool
182 IsInterfacePrototype(DOMObjectType type)
184 return type == eInterfacePrototype || type == eGlobalInterfacePrototype;
187 typedef JSObject* (*ParentGetter)(JSContext* aCx, JS::Handle<JSObject*> aObj);
189 typedef JSObject* (*ProtoGetter)(JSContext* aCx,
190 JS::Handle<JSObject*> aGlobal);
192 * Returns a handle to the relevent WebIDL prototype object for the given global
193 * (which may be a handle to null on out of memory). Once allocated, the
194 * prototype object is guaranteed to exist as long as the global does, since the
195 * global traces its array of WebIDL prototypes and constructors.
197 typedef JS::Handle<JSObject*> (*ProtoHandleGetter)(JSContext* aCx,
198 JS::Handle<JSObject*> aGlobal);
200 // Special JSClass for reflected DOM objects.
201 struct DOMJSClass
203 // It would be nice to just inherit from JSClass, but that precludes pure
204 // compile-time initialization of the form |DOMJSClass = {...};|, since C++
205 // only allows brace initialization for aggregate/POD types.
206 const js::Class mBase;
208 // A list of interfaces that this object implements, in order of decreasing
209 // derivedness.
210 const prototypes::ID mInterfaceChain[MAX_PROTOTYPE_CHAIN_LENGTH];
212 // We store the DOM object in reserved slot with index DOM_OBJECT_SLOT or in
213 // the proxy private if we use a proxy object.
214 // Sometimes it's an nsISupports and sometimes it's not; this class tells
215 // us which it is.
216 const bool mDOMObjectIsISupports;
218 const NativePropertyHooks* mNativeHooks;
220 ParentGetter mGetParent;
221 ProtoHandleGetter mGetProto;
223 // This stores the CC participant for the native, null if this class is for a
224 // worker or for a native inheriting from nsISupports (we can get the CC
225 // participant by QI'ing in that case).
226 nsCycleCollectionParticipant* mParticipant;
228 static const DOMJSClass* FromJSClass(const JSClass* base) {
229 MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
230 return reinterpret_cast<const DOMJSClass*>(base);
233 static const DOMJSClass* FromJSClass(const js::Class* base) {
234 return FromJSClass(Jsvalify(base));
237 const JSClass* ToJSClass() const { return Jsvalify(&mBase); }
240 // Special JSClass for DOM interface and interface prototype objects.
241 struct DOMIfaceAndProtoJSClass
243 // It would be nice to just inherit from js::Class, but that precludes pure
244 // compile-time initialization of the form
245 // |DOMJSInterfaceAndPrototypeClass = {...};|, since C++ only allows brace
246 // initialization for aggregate/POD types.
247 const js::Class mBase;
249 // Either eInterface, eInterfacePrototype, eGlobalInterfacePrototype or
250 // eNamedPropertiesObject.
251 DOMObjectType mType;
253 const NativePropertyHooks* mNativeHooks;
255 // The value to return for toString() on this interface or interface prototype
256 // object.
257 const char* mToString;
259 const prototypes::ID mPrototypeID;
260 const uint32_t mDepth;
262 ProtoGetter mGetParentProto;
264 static const DOMIfaceAndProtoJSClass* FromJSClass(const JSClass* base) {
265 MOZ_ASSERT(base->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS);
266 return reinterpret_cast<const DOMIfaceAndProtoJSClass*>(base);
268 static const DOMIfaceAndProtoJSClass* FromJSClass(const js::Class* base) {
269 return FromJSClass(Jsvalify(base));
272 const JSClass* ToJSClass() const { return Jsvalify(&mBase); }
275 class ProtoAndIfaceCache;
277 inline bool
278 HasProtoAndIfaceCache(JSObject* global)
280 MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
281 // This can be undefined if we GC while creating the global
282 return !js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).isUndefined();
285 inline ProtoAndIfaceCache*
286 GetProtoAndIfaceCache(JSObject* global)
288 MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
289 return static_cast<ProtoAndIfaceCache*>(
290 js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).toPrivate());
293 } // namespace dom
294 } // namespace mozilla
296 #endif /* mozilla_dom_DOMJSClass_h */