Bumping manifests a=b2g-bump
[gecko.git] / js / src / jswrapper.h
blob89c9ce037e1a0698f59bb6e28d9b864866c6e2a6
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),
27 proto_()
30 explicit WrapperOptions(JSContext* cx) : ProxyOptions(false),
31 proto_()
33 proto_.emplace(cx);
36 inline JSObject* proto() const;
37 WrapperOptions& setProto(JSObject* protoArg) {
38 MOZ_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 the
50 * methods in various ways. A wrapper is distinct from a Direct Proxy Handler
51 * 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
55 * context.
57 class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
59 unsigned mFlags;
61 public:
62 using BaseProxyHandler::Action;
64 enum Flags {
65 CROSS_COMPARTMENT = 1 << 0,
66 LAST_USED_FLAG = CROSS_COMPARTMENT
69 virtual bool defaultValue(JSContext* cx, HandleObject obj, JSType hint,
70 MutableHandleValue vp) const MOZ_OVERRIDE;
72 static JSObject* New(JSContext* cx, JSObject* obj, JSObject* parent, const Wrapper* handler,
73 const WrapperOptions& options = WrapperOptions());
75 static JSObject* Renew(JSContext* cx, JSObject* existing, JSObject* obj, const Wrapper* handler);
77 static const Wrapper* wrapperHandler(JSObject* wrapper);
79 static JSObject* wrappedObject(JSObject* wrapper);
81 unsigned flags() const {
82 return mFlags;
85 explicit MOZ_CONSTEXPR Wrapper(unsigned aFlags, bool aHasPrototype = false,
86 bool aHasSecurityPolicy = false)
87 : DirectProxyHandler(&family, aHasPrototype, aHasSecurityPolicy),
88 mFlags(aFlags)
89 { }
91 virtual bool finalizeInBackground(Value priv) const MOZ_OVERRIDE;
92 virtual bool isConstructor(JSObject* obj) const MOZ_OVERRIDE;
94 static const char family;
95 static const Wrapper singleton;
96 static const Wrapper singletonWithPrototype;
98 static JSObject* defaultProto;
101 inline JSObject*
102 WrapperOptions::proto() const
104 return proto_ ? *proto_ : Wrapper::defaultProto;
107 /* Base class for all cross compartment wrapper handlers. */
108 class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
110 public:
111 explicit MOZ_CONSTEXPR CrossCompartmentWrapper(unsigned aFlags, bool aHasPrototype = false,
112 bool aHasSecurityPolicy = false)
113 : Wrapper(CROSS_COMPARTMENT | aFlags, aHasPrototype, aHasSecurityPolicy)
116 /* Standard internal methods. */
117 virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
118 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
119 virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
120 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
121 virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper,
122 AutoIdVector& props) const MOZ_OVERRIDE;
123 virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const MOZ_OVERRIDE;
124 virtual bool enumerate(JSContext* cx, HandleObject wrapper, MutableHandleObject objp) const MOZ_OVERRIDE;
125 virtual bool getPrototypeOf(JSContext* cx, HandleObject proxy,
126 MutableHandleObject protop) const MOZ_OVERRIDE;
127 virtual bool setPrototypeOf(JSContext* cx, HandleObject proxy, HandleObject proto,
128 bool* bp) const MOZ_OVERRIDE;
130 virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy,
131 bool* succeeded) const MOZ_OVERRIDE;
132 virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, bool* succeeded) const MOZ_OVERRIDE;
133 virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const MOZ_OVERRIDE;
134 virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const MOZ_OVERRIDE;
135 virtual bool get(JSContext* cx, HandleObject wrapper, HandleObject receiver,
136 HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE;
137 virtual bool set(JSContext* cx, HandleObject wrapper, HandleObject receiver,
138 HandleId id, bool strict, MutableHandleValue vp) const MOZ_OVERRIDE;
139 virtual bool call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const MOZ_OVERRIDE;
140 virtual bool construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const MOZ_OVERRIDE;
142 /* SpiderMonkey extensions. */
143 virtual bool getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
144 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
145 virtual bool hasOwn(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const MOZ_OVERRIDE;
146 virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper,
147 AutoIdVector& props) const MOZ_OVERRIDE;
148 virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
149 CallArgs args) const MOZ_OVERRIDE;
150 virtual bool hasInstance(JSContext* cx, HandleObject wrapper, MutableHandleValue v,
151 bool* bp) const MOZ_OVERRIDE;
152 virtual const char* className(JSContext* cx, HandleObject proxy) const MOZ_OVERRIDE;
153 virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper,
154 unsigned indent) const MOZ_OVERRIDE;
155 virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const MOZ_OVERRIDE;
156 virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const MOZ_OVERRIDE;
157 virtual bool defaultValue(JSContext* cx, HandleObject wrapper, JSType hint,
158 MutableHandleValue vp) const MOZ_OVERRIDE;
160 static const CrossCompartmentWrapper singleton;
161 static const CrossCompartmentWrapper singletonWithPrototype;
165 * Base class for security wrappers. A security wrapper is potentially hiding
166 * all or part of some wrapped object thus SecurityWrapper defaults to denying
167 * access to the wrappee. This is the opposite of Wrapper which tries to be
168 * completely transparent.
170 * NB: Currently, only a few ProxyHandler operations are overridden to deny
171 * access, relying on derived SecurityWrapper to block access when necessary.
173 template <class Base>
174 class JS_FRIEND_API(SecurityWrapper) : public Base
176 public:
177 explicit MOZ_CONSTEXPR SecurityWrapper(unsigned flags, bool hasPrototype = false)
178 : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true)
181 virtual bool enter(JSContext* cx, HandleObject wrapper, HandleId id, Wrapper::Action act,
182 bool* bp) const MOZ_OVERRIDE;
184 virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
185 MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
186 virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const MOZ_OVERRIDE;
187 virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, bool* succeeded) const MOZ_OVERRIDE;
188 virtual bool setPrototypeOf(JSContext* cx, HandleObject proxy, HandleObject proto,
189 bool* bp) const MOZ_OVERRIDE;
190 virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const MOZ_OVERRIDE;
192 virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
193 CallArgs args) const MOZ_OVERRIDE;
194 virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
195 JSContext* cx) const MOZ_OVERRIDE;
196 virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const MOZ_OVERRIDE;
197 virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const MOZ_OVERRIDE;
198 virtual bool defaultValue(JSContext* cx, HandleObject wrapper, JSType hint,
199 MutableHandleValue vp) const MOZ_OVERRIDE;
201 // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded
202 // against.
204 virtual bool watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
205 JS::HandleObject callable) const MOZ_OVERRIDE;
206 virtual bool unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id) const MOZ_OVERRIDE;
209 * Allow our subclasses to select the superclass behavior they want without
210 * needing to specify an exact superclass.
212 typedef Base Permissive;
213 typedef SecurityWrapper<Base> Restrictive;
216 typedef SecurityWrapper<Wrapper> SameCompartmentSecurityWrapper;
217 typedef SecurityWrapper<CrossCompartmentWrapper> CrossCompartmentSecurityWrapper;
219 extern JSObject*
220 TransparentObjectWrapper(JSContext* cx, HandleObject existing, HandleObject obj,
221 HandleObject parent);
223 inline bool
224 IsWrapper(JSObject* obj)
226 return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family;
229 // Given a JSObject, returns that object stripped of wrappers. If
230 // stopAtOuter is true, then this returns the outer window if it was
231 // previously wrapped. Otherwise, this returns the first object for
232 // which JSObject::isWrapper returns false.
233 JS_FRIEND_API(JSObject*)
234 UncheckedUnwrap(JSObject* obj, bool stopAtOuter = true, unsigned* flagsp = nullptr);
236 // Given a JSObject, returns that object stripped of wrappers. At each stage,
237 // the security wrapper has the opportunity to veto the unwrap. Since checked
238 // code should never be unwrapping outer window wrappers, we always stop at
239 // outer windows.
240 JS_FRIEND_API(JSObject*)
241 CheckedUnwrap(JSObject* obj, bool stopAtOuter = true);
243 // Unwrap only the outermost security wrapper, with the same semantics as
244 // above. This is the checked version of Wrapper::wrappedObject.
245 JS_FRIEND_API(JSObject*)
246 UnwrapOneChecked(JSObject* obj, bool stopAtOuter = true);
248 JS_FRIEND_API(bool)
249 IsCrossCompartmentWrapper(JSObject* obj);
251 void
252 NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper);
254 bool
255 RemapWrapper(JSContext* cx, JSObject* wobj, JSObject* newTarget);
257 JS_FRIEND_API(bool)
258 RemapAllWrappersForObject(JSContext* cx, JSObject* oldTarget,
259 JSObject* newTarget);
261 // API to recompute all cross-compartment wrappers whose source and target
262 // match the given filters.
263 JS_FRIEND_API(bool)
264 RecomputeWrappers(JSContext* cx, const CompartmentFilter& sourceFilter,
265 const CompartmentFilter& targetFilter);
267 } /* namespace js */
269 #endif /* jswrapper_h */