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
32 (* ResolveOwnProperty
)(JSContext
* cx
, JS::Handle
<JSObject
*> wrapper
,
33 JS::Handle
<JSObject
*> obj
, JS::Handle
<jsid
> id
,
34 JS::MutableHandle
<JSPropertyDescriptor
> desc
);
37 (* EnumerateOwnProperties
)(JSContext
* cx
, JS::Handle
<JSObject
*> wrapper
,
38 JS::Handle
<JSObject
*> obj
,
39 JS::AutoIdVector
& props
);
42 CheckPermissions(JSContext
* aCx
, JSObject
* aObj
, const char* const aPermissions
[]);
50 typedef bool (*PropertyEnabled
)(JSContext
* cx
, JSObject
* global
);
54 inline bool isEnabled(JSContext
* cx
, JSObject
* obj
) const {
58 if (!enabledFunc
&& !availableFunc
&& !checkPermissions
) {
61 // Just go ahead and root obj, in case enabledFunc GCs
62 JS::Rooted
<JSObject
*> rootedObj(cx
, obj
);
64 !enabledFunc(cx
, js::GetGlobalForObjectCrossCompartment(rootedObj
))) {
68 !availableFunc(cx
, js::GetGlobalForObjectCrossCompartment(rootedObj
))) {
71 if (checkPermissions
&&
72 !CheckPermissions(cx
, js::GetGlobalForObjectCrossCompartment(rootedObj
),
79 // A boolean indicating whether this set of specs is 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.
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
;
109 const JSFunctionSpec
* methodSpecs
;
111 const Prefable
<const JSPropertySpec
>* attributes
;
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
;
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
;
169 eGlobalInterfacePrototype
,
170 eNamedPropertiesObject
175 IsInstance(DOMObjectType type
)
177 return type
== eInstance
|| type
== eGlobalInstance
;
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.
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
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
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.
253 const NativePropertyHooks
* mNativeHooks
;
255 // The value to return for toString() on this interface or interface prototype
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
;
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());
294 } // namespace mozilla
296 #endif /* mozilla_dom_DOMJSClass_h */