Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 struct ConstantSpec
42 {
43 const char* name;
44 JS::Value value;
45 };
47 typedef bool (*PropertyEnabled)(JSContext* cx, JSObject* global);
49 template<typename T>
50 struct Prefable {
51 inline bool isEnabled(JSContext* cx, JSObject* obj) const {
52 if (!enabled) {
53 return false;
54 }
55 if (!enabledFunc && !availableFunc) {
56 return true;
57 }
58 // Just go ahead and root obj, in case enabledFunc GCs
59 JS::Rooted<JSObject*> rootedObj(cx, obj);
60 if (enabledFunc &&
61 !enabledFunc(cx, js::GetGlobalForObjectCrossCompartment(rootedObj))) {
62 return false;
63 }
64 if (availableFunc &&
65 !availableFunc(cx, js::GetGlobalForObjectCrossCompartment(rootedObj))) {
66 return false;
67 }
68 return true;
69 }
71 // A boolean indicating whether this set of specs is enabled
72 bool enabled;
73 // A function pointer to a function that can say the property is disabled
74 // even if "enabled" is set to true. If the pointer is null the value of
75 // "enabled" is used as-is unless availableFunc overrides.
76 PropertyEnabled enabledFunc;
77 // A function pointer to a function that can be used to disable a
78 // property even if "enabled" is true and enabledFunc allowed. This
79 // is basically a hack to avoid having to codegen PropertyEnabled
80 // implementations in case when we need to do two separate checks.
81 PropertyEnabled availableFunc;
82 // Array of specs, terminated in whatever way is customary for T.
83 // Null to indicate a end-of-array for Prefable, when such an
84 // indicator is needed.
85 const T* specs;
86 };
88 struct NativeProperties
89 {
90 const Prefable<const JSFunctionSpec>* staticMethods;
91 jsid* staticMethodIds;
92 const JSFunctionSpec* staticMethodsSpecs;
93 const Prefable<const JSPropertySpec>* staticAttributes;
94 jsid* staticAttributeIds;
95 const JSPropertySpec* staticAttributeSpecs;
96 const Prefable<const JSFunctionSpec>* methods;
97 jsid* methodIds;
98 const JSFunctionSpec* methodsSpecs;
99 const Prefable<const JSPropertySpec>* attributes;
100 jsid* attributeIds;
101 const JSPropertySpec* attributeSpecs;
102 const Prefable<const JSPropertySpec>* unforgeableAttributes;
103 jsid* unforgeableAttributeIds;
104 const JSPropertySpec* unforgeableAttributeSpecs;
105 const Prefable<const ConstantSpec>* constants;
106 jsid* constantIds;
107 const ConstantSpec* constantSpecs;
108 };
110 struct NativePropertiesHolder
111 {
112 const NativeProperties* regular;
113 const NativeProperties* chromeOnly;
114 };
116 // Helper structure for Xrays for DOM binding objects. The same instance is used
117 // for instances, interface objects and interface prototype objects of a
118 // specific interface.
119 struct NativePropertyHooks
120 {
121 // The hook to call for resolving indexed or named properties. May be null if
122 // there can't be any.
123 ResolveOwnProperty mResolveOwnProperty;
124 // The hook to call for enumerating indexed or named properties. May be null
125 // if there can't be any.
126 EnumerateOwnProperties mEnumerateOwnProperties;
128 // The property arrays for this interface.
129 NativePropertiesHolder mNativeProperties;
131 // This will be set to the ID of the interface prototype object for the
132 // interface, if it has one. If it doesn't have one it will be set to
133 // prototypes::id::_ID_Count.
134 prototypes::ID mPrototypeID;
136 // This will be set to the ID of the interface object for the interface, if it
137 // has one. If it doesn't have one it will be set to
138 // constructors::id::_ID_Count.
139 constructors::ID mConstructorID;
141 // The NativePropertyHooks instance for the parent interface.
142 const NativePropertyHooks* mProtoHooks;
143 };
145 enum DOMObjectType {
146 eInstance,
147 eInterface,
148 eInterfacePrototype
149 };
151 typedef JSObject* (*ParentGetter)(JSContext* aCx, JS::Handle<JSObject*> aObj);
152 /**
153 * Returns a handle to the relevent WebIDL prototype object for the given global
154 * (which may be a handle to null on out of memory). Once allocated, the
155 * prototype object is guaranteed to exist as long as the global does, since the
156 * global traces its array of WebIDL prototypes and constructors.
157 */
158 typedef JS::Handle<JSObject*> (*ProtoGetter)(JSContext* aCx,
159 JS::Handle<JSObject*> aGlobal);
161 struct DOMClass
162 {
163 // A list of interfaces that this object implements, in order of decreasing
164 // derivedness.
165 const prototypes::ID mInterfaceChain[MAX_PROTOTYPE_CHAIN_LENGTH];
167 // We store the DOM object in reserved slot with index DOM_OBJECT_SLOT or in
168 // the proxy private if we use a proxy object.
169 // Sometimes it's an nsISupports and sometimes it's not; this class tells
170 // us which it is.
171 const bool mDOMObjectIsISupports;
173 const NativePropertyHooks* mNativeHooks;
175 ParentGetter mGetParent;
176 ProtoGetter mGetProto;
178 // This stores the CC participant for the native, null if this class is for a
179 // worker or for a native inheriting from nsISupports (we can get the CC
180 // participant by QI'ing in that case).
181 nsCycleCollectionParticipant* mParticipant;
182 };
184 // Special JSClass for reflected DOM objects.
185 struct DOMJSClass
186 {
187 // It would be nice to just inherit from JSClass, but that precludes pure
188 // compile-time initialization of the form |DOMJSClass = {...};|, since C++
189 // only allows brace initialization for aggregate/POD types.
190 const js::Class mBase;
192 const DOMClass mClass;
194 static const DOMJSClass* FromJSClass(const JSClass* base) {
195 MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
196 return reinterpret_cast<const DOMJSClass*>(base);
197 }
199 static const DOMJSClass* FromJSClass(const js::Class* base) {
200 return FromJSClass(Jsvalify(base));
201 }
203 const JSClass* ToJSClass() const { return Jsvalify(&mBase); }
204 };
206 // Special JSClass for DOM interface and interface prototype objects.
207 struct DOMIfaceAndProtoJSClass
208 {
209 // It would be nice to just inherit from JSClass, but that precludes pure
210 // compile-time initialization of the form
211 // |DOMJSInterfaceAndPrototypeClass = {...};|, since C++ only allows brace
212 // initialization for aggregate/POD types.
213 const JSClass mBase;
215 // Either eInterface or eInterfacePrototype
216 DOMObjectType mType;
218 const NativePropertyHooks* mNativeHooks;
220 // The value to return for toString() on this interface or interface prototype
221 // object.
222 const char* mToString;
224 const prototypes::ID mPrototypeID;
225 const uint32_t mDepth;
227 static const DOMIfaceAndProtoJSClass* FromJSClass(const JSClass* base) {
228 MOZ_ASSERT(base->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS);
229 return reinterpret_cast<const DOMIfaceAndProtoJSClass*>(base);
230 }
231 static const DOMIfaceAndProtoJSClass* FromJSClass(const js::Class* base) {
232 return FromJSClass(Jsvalify(base));
233 }
235 const JSClass* ToJSClass() const { return &mBase; }
236 };
238 class ProtoAndIfaceCache;
240 inline bool
241 HasProtoAndIfaceCache(JSObject* global)
242 {
243 MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
244 // This can be undefined if we GC while creating the global
245 return !js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).isUndefined();
246 }
248 inline ProtoAndIfaceCache*
249 GetProtoAndIfaceCache(JSObject* global)
250 {
251 MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
252 return static_cast<ProtoAndIfaceCache*>(
253 js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).toPrivate());
254 }
256 } // namespace dom
257 } // namespace mozilla
259 #endif /* mozilla_dom_DOMJSClass_h */