Bumping manifests a=b2g-bump
[gecko.git] / js / src / jswrapper.h
blob3751277b8fbe04489adbebcf03def775065ce4f5
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jswrapper_h
8 #define jswrapper_h
10 #include "mozilla/Attributes.h"
12 #include "jsproxy.h"
14 namespace js {
16 class DummyFrameGuard;
19 * Helper for Wrapper::New default options.
21 * Callers of Wrapper::New() who wish to specify a prototype for the created
22 * Wrapper, *MUST* construct a WrapperOptions with a JSContext.
24 class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions {
25 public:
26 WrapperOptions() : ProxyOptions(false, nullptr),
27 proto_()
30 explicit WrapperOptions(JSContext* cx) : ProxyOptions(false, nullptr),
31 proto_()
33 proto_.emplace(cx);
36 inline JSObject* proto() const;
37 WrapperOptions& setProto(JSObject* protoArg) {
38 JS_ASSERT(proto_);
39 *proto_ = protoArg;
40 return *this;
43 private:
44 mozilla::Maybe<JS::RootedObject> proto_;
48 * A wrapper is a proxy with a target object to which it generally forwards
49 * operations, but may restrict access to certain operations or instrument
50 * the trap operations in various ways. A wrapper is distinct from a Direct Proxy
51 * Handler in the sense that it can be "unwrapped" in C++, exposing the underlying
52 * object (Direct Proxy Handlers have an underlying target object, but don't
53 * expect to expose this object via any kind of unwrapping operation). Callers
54 * should be careful to avoid unwrapping security wrappers in the wrong context.
56 class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
58 unsigned mFlags;
60 public:
61 using BaseProxyHandler::Action;
63 enum Flags {
64 CROSS_COMPARTMENT = 1 << 0,
65 LAST_USED_FLAG = CROSS_COMPARTMENT
68 virtual bool defaultValue(JSContext* cx, HandleObject obj, JSType hint,
69 MutableHandleValue vp) const MOZ_OVERRIDE;
71 static JSObject* New(JSContext* cx, JSObject* obj, JSObject* parent, const Wrapper* handler,
72 const WrapperOptions* options = nullptr);
74 static JSObject* Renew(JSContext* cx, JSObject* existing, JSObject* obj, const Wrapper* handler);
76 static const Wrapper* wrapperHandler(JSObject* wrapper);
78 static JSObject* wrappedObject(JSObject* wrapper);
80 unsigned flags() const {
81 return mFlags;
84 explicit MOZ_CONSTEXPR Wrapper(unsigned aFlags, bool aHasPrototype = false,
85 bool aHasSecurityPolicy = false)
86 : DirectProxyHandler(&family, aHasPrototype, aHasSecurityPolicy),
87 mFlags(aFlags)
88 { }
90 virtual bool finalizeInBackground(Value priv) const MOZ_OVERRIDE;
92 static const char family;
93 static const Wrapper singleton;
94 static const Wrapper singletonWithPrototype;
96 static JSObject* defaultProto;
99 inline JSObject*
100 WrapperOptions::proto() const
102 return proto_ ? *proto_ : Wrapper::defaultProto;
105 /* Base class for all cross compartment wrapper handlers. */
106 class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
108 public:
109 explicit MOZ_CONSTEXPR CrossCompartmentWrapper(unsigned aFlags, bool aHasPrototype = false,
110 bool aHasSecurityPolicy = false)
111 : Wrapper(CROSS_COMPARTMENT | aFlags, aHasPrototype, aHasSecurityPolicy)
114 /* ES5 Harmony fundamental wrapper traps. */
115 virtual bool preventExtensions(JSContext* cx, HandleObject wrapper) const MOZ_OVERRIDE;
116 virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
117 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
118 virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
119 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
120 virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
121 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
122 virtual bool getOwnPropertyNames(JSContext* cx, HandleObject wrapper,
123 AutoIdVector& props) const MOZ_OVERRIDE;
124 virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const MOZ_OVERRIDE;
125 virtual bool enumerate(JSContext* cx, HandleObject wrapper, AutoIdVector& props) const MOZ_OVERRIDE;
127 /* ES5 Harmony derived wrapper traps. */
128 virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const MOZ_OVERRIDE;
129 virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const MOZ_OVERRIDE;
130 virtual bool get(JSContext* cx, HandleObject wrapper, HandleObject receiver,
131 HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE;
132 virtual bool set(JSContext* cx, HandleObject wrapper, HandleObject receiver,
133 HandleId id, bool strict, MutableHandleValue vp) const MOZ_OVERRIDE;
134 virtual bool keys(JSContext* cx, HandleObject wrapper, AutoIdVector& props) const MOZ_OVERRIDE;
135 virtual bool iterate(JSContext* cx, HandleObject wrapper, unsigned flags,
136 MutableHandleValue vp) const MOZ_OVERRIDE;
138 /* Spidermonkey extensions. */
139 virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const MOZ_OVERRIDE;
140 virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const MOZ_OVERRIDE;
141 virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const MOZ_OVERRIDE;
142 virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
143 CallArgs args) const MOZ_OVERRIDE;
144 virtual bool hasInstance(JSContext* cx, HandleObject wrapper, MutableHandleValue v,
145 bool* bp) const MOZ_OVERRIDE;
146 virtual const char* className(JSContext* cx, HandleObject proxy) const MOZ_OVERRIDE;
147 virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper,
148 unsigned indent) const MOZ_OVERRIDE;
149 virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const MOZ_OVERRIDE;
150 virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const MOZ_OVERRIDE;
151 virtual bool defaultValue(JSContext* cx, HandleObject wrapper, JSType hint,
152 MutableHandleValue vp) const MOZ_OVERRIDE;
153 virtual bool getPrototypeOf(JSContext* cx, HandleObject proxy,
154 MutableHandleObject protop) const MOZ_OVERRIDE;
155 virtual bool setPrototypeOf(JSContext* cx, HandleObject proxy, HandleObject proto,
156 bool* bp) const MOZ_OVERRIDE;
158 static const CrossCompartmentWrapper singleton;
159 static const CrossCompartmentWrapper singletonWithPrototype;
163 * Base class for security wrappers. A security wrapper is potentially hiding
164 * all or part of some wrapped object thus SecurityWrapper defaults to denying
165 * access to the wrappee. This is the opposite of Wrapper which tries to be
166 * completely transparent.
168 * NB: Currently, only a few ProxyHandler operations are overridden to deny
169 * access, relying on derived SecurityWrapper to block access when necessary.
171 template <class Base>
172 class JS_FRIEND_API(SecurityWrapper) : public Base
174 public:
175 explicit MOZ_CONSTEXPR SecurityWrapper(unsigned flags, bool hasPrototype = false)
176 : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true)
179 virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const MOZ_OVERRIDE;
180 virtual bool preventExtensions(JSContext* cx, HandleObject wrapper) const MOZ_OVERRIDE;
181 virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Wrapper::Action act,
182 bool* bp) const MOZ_OVERRIDE;
183 virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
184 CallArgs args) const MOZ_OVERRIDE;
185 virtual bool defaultValue(JSContext* cx, HandleObject wrapper, JSType hint,
186 MutableHandleValue vp) const MOZ_OVERRIDE;
187 virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
188 JSContext* cx) const MOZ_OVERRIDE;
189 virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const MOZ_OVERRIDE;
190 virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const MOZ_OVERRIDE;
191 virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
192 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
194 virtual bool setPrototypeOf(JSContext* cx, HandleObject proxy, HandleObject proto,
195 bool* bp) const MOZ_OVERRIDE;
197 virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
198 JS::HandleObject callable) const MOZ_OVERRIDE;
199 virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const MOZ_OVERRIDE;
202 * Allow our subclasses to select the superclass behavior they want without
203 * needing to specify an exact superclass.
205 typedef Base Permissive;
206 typedef SecurityWrapper<Base> Restrictive;
209 typedef SecurityWrapper<Wrapper> SameCompartmentSecurityWrapper;
210 typedef SecurityWrapper<CrossCompartmentWrapper> CrossCompartmentSecurityWrapper;
212 class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
214 public:
215 explicit MOZ_CONSTEXPR DeadObjectProxy()
216 : BaseProxyHandler(&family)
219 /* ES5 Harmony fundamental wrapper traps. */
220 virtual bool preventExtensions(JSContext* cx, HandleObject proxy) const MOZ_OVERRIDE;
221 virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
222 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
223 virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
224 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
225 virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
226 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
227 virtual bool getOwnPropertyNames(JSContext* cx, HandleObject wrapper,
228 AutoIdVector& props) const MOZ_OVERRIDE;
229 virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const MOZ_OVERRIDE;
230 virtual bool enumerate(JSContext* cx, HandleObject wrapper, AutoIdVector& props) const MOZ_OVERRIDE;
232 /* Spidermonkey extensions. */
233 virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const MOZ_OVERRIDE;
234 virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const MOZ_OVERRIDE;
235 virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const MOZ_OVERRIDE;
236 virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
237 CallArgs args) const MOZ_OVERRIDE;
238 virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
239 bool* bp) const MOZ_OVERRIDE;
240 virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
241 JSContext* cx) const MOZ_OVERRIDE;
242 virtual const char* className(JSContext* cx, HandleObject proxy) const MOZ_OVERRIDE;
243 virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const MOZ_OVERRIDE;
244 virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const MOZ_OVERRIDE;
245 virtual bool defaultValue(JSContext* cx, HandleObject obj, JSType hint,
246 MutableHandleValue vp) const MOZ_OVERRIDE;
247 virtual bool getPrototypeOf(JSContext* cx, HandleObject proxy,
248 MutableHandleObject protop) const MOZ_OVERRIDE;
250 static const char family;
251 static const DeadObjectProxy singleton;
254 extern JSObject*
255 TransparentObjectWrapper(JSContext* cx, HandleObject existing, HandleObject obj,
256 HandleObject parent);
258 inline bool
259 IsWrapper(JSObject* obj)
261 return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family;
264 // Given a JSObject, returns that object stripped of wrappers. If
265 // stopAtOuter is true, then this returns the outer window if it was
266 // previously wrapped. Otherwise, this returns the first object for
267 // which JSObject::isWrapper returns false.
268 JS_FRIEND_API(JSObject*)
269 UncheckedUnwrap(JSObject* obj, bool stopAtOuter = true, unsigned* flagsp = nullptr);
271 // Given a JSObject, returns that object stripped of wrappers. At each stage,
272 // the security wrapper has the opportunity to veto the unwrap. Since checked
273 // code should never be unwrapping outer window wrappers, we always stop at
274 // outer windows.
275 JS_FRIEND_API(JSObject*)
276 CheckedUnwrap(JSObject* obj, bool stopAtOuter = true);
278 // Unwrap only the outermost security wrapper, with the same semantics as
279 // above. This is the checked version of Wrapper::wrappedObject.
280 JS_FRIEND_API(JSObject*)
281 UnwrapOneChecked(JSObject* obj, bool stopAtOuter = true);
283 JS_FRIEND_API(bool)
284 IsCrossCompartmentWrapper(JSObject* obj);
286 bool
287 IsDeadProxyObject(JSObject* obj);
289 JSObject*
290 NewDeadProxyObject(JSContext* cx, JSObject* parent,
291 const ProxyOptions& options = ProxyOptions());
293 void
294 NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper);
296 bool
297 RemapWrapper(JSContext* cx, JSObject* wobj, JSObject* newTarget);
299 JS_FRIEND_API(bool)
300 RemapAllWrappersForObject(JSContext* cx, JSObject* oldTarget,
301 JSObject* newTarget);
303 // API to recompute all cross-compartment wrappers whose source and target
304 // match the given filters.
305 JS_FRIEND_API(bool)
306 RecomputeWrappers(JSContext* cx, const CompartmentFilter& sourceFilter,
307 const CompartmentFilter& targetFilter);
309 } /* namespace js */
311 #endif /* jswrapper_h */