Bug 1027964 - Standardize proxy handler families. (r=jorendorff)
This commit is contained in:
@@ -29,8 +29,7 @@ DefineStaticJSVals(JSContext* cx)
|
|||||||
return InternJSString(cx, s_length_id, "length");
|
return InternJSString(cx, s_length_id, "length");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char DOMProxyHandler::family = 0;
|
||||||
const char HandlerFamily = 0;
|
|
||||||
|
|
||||||
js::DOMProxyShadowsResult
|
js::DOMProxyShadowsResult
|
||||||
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
|
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
|
||||||
@@ -60,7 +59,7 @@ DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
|
|||||||
struct SetDOMProxyInformation
|
struct SetDOMProxyInformation
|
||||||
{
|
{
|
||||||
SetDOMProxyInformation() {
|
SetDOMProxyInformation() {
|
||||||
js::SetDOMProxyInformation((const void*) &HandlerFamily,
|
js::SetDOMProxyInformation((const void*) &DOMProxyHandler::family,
|
||||||
js::PROXY_EXTRA_SLOT + JSPROXYSLOT_EXPANDO, DOMProxyShadows);
|
js::PROXY_EXTRA_SLOT + JSPROXYSLOT_EXPANDO, DOMProxyShadows);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -363,5 +362,25 @@ DOMProxyHandler::setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handl
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
JSObject *
|
||||||
|
DOMProxyHandler::GetExpandoObject(JSObject *obj)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
||||||
|
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
||||||
|
if (v.isObject()) {
|
||||||
|
return &v.toObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.isUndefined()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
js::ExpandoAndGeneration* expandoAndGeneration =
|
||||||
|
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||||
|
v = expandoAndGeneration->expando;
|
||||||
|
return v.isUndefined() ? nullptr : &v.toObject();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -24,17 +24,6 @@ enum {
|
|||||||
|
|
||||||
template<typename T> struct Prefable;
|
template<typename T> struct Prefable;
|
||||||
|
|
||||||
// This variable exists solely to provide a unique address for use as an identifier.
|
|
||||||
extern const char HandlerFamily;
|
|
||||||
inline const void* ProxyFamily() { return &HandlerFamily; }
|
|
||||||
|
|
||||||
inline bool IsDOMProxy(JSObject *obj)
|
|
||||||
{
|
|
||||||
const js::Class* clasp = js::GetObjectClass(obj);
|
|
||||||
return clasp->isProxy() &&
|
|
||||||
js::GetProxyHandler(obj)->family() == ProxyFamily();
|
|
||||||
}
|
|
||||||
|
|
||||||
class BaseDOMProxyHandler : public js::BaseProxyHandler
|
class BaseDOMProxyHandler : public js::BaseProxyHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -89,7 +78,7 @@ class DOMProxyHandler : public BaseDOMProxyHandler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DOMProxyHandler()
|
DOMProxyHandler()
|
||||||
: BaseDOMProxyHandler(ProxyFamily())
|
: BaseDOMProxyHandler(&family)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,29 +110,23 @@ public:
|
|||||||
virtual bool setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
virtual bool setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||||
JS::MutableHandle<JS::Value> vp, bool *done) const;
|
JS::MutableHandle<JS::Value> vp, bool *done) const;
|
||||||
|
|
||||||
static JSObject* GetExpandoObject(JSObject* obj)
|
static JSObject* GetExpandoObject(JSObject* obj);
|
||||||
{
|
|
||||||
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
|
||||||
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
|
||||||
if (v.isObject()) {
|
|
||||||
return &v.toObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v.isUndefined()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
js::ExpandoAndGeneration* expandoAndGeneration =
|
|
||||||
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
||||||
v = expandoAndGeneration->expando;
|
|
||||||
return v.isUndefined() ? nullptr : &v.toObject();
|
|
||||||
}
|
|
||||||
/* GetAndClearExpandoObject does not DROP or clear the preserving wrapper flag. */
|
/* GetAndClearExpandoObject does not DROP or clear the preserving wrapper flag. */
|
||||||
static JSObject* GetAndClearExpandoObject(JSObject* obj);
|
static JSObject* GetAndClearExpandoObject(JSObject* obj);
|
||||||
static JSObject* EnsureExpandoObject(JSContext* cx,
|
static JSObject* EnsureExpandoObject(JSContext* cx,
|
||||||
JS::Handle<JSObject*> obj);
|
JS::Handle<JSObject*> obj);
|
||||||
|
|
||||||
|
static const char family;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool IsDOMProxy(JSObject *obj)
|
||||||
|
{
|
||||||
|
const js::Class* clasp = js::GetObjectClass(obj);
|
||||||
|
return clasp->isProxy() &&
|
||||||
|
js::GetProxyHandler(obj)->family() == &DOMProxyHandler::family;
|
||||||
|
}
|
||||||
|
|
||||||
inline const DOMProxyHandler*
|
inline const DOMProxyHandler*
|
||||||
GetDOMProxyHandler(JSObject* obj)
|
GetDOMProxyHandler(JSObject* obj)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,13 +45,11 @@ WrapperOwner::idOf(JSObject *obj)
|
|||||||
return objId;
|
return objId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sCPOWProxyHandler;
|
|
||||||
|
|
||||||
class CPOWProxyHandler : public BaseProxyHandler
|
class CPOWProxyHandler : public BaseProxyHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPOWProxyHandler()
|
CPOWProxyHandler()
|
||||||
: BaseProxyHandler(&sCPOWProxyHandler) {}
|
: BaseProxyHandler(&family) {}
|
||||||
virtual ~CPOWProxyHandler() {}
|
virtual ~CPOWProxyHandler() {}
|
||||||
|
|
||||||
virtual bool finalizeInBackground(Value priv) const MOZ_OVERRIDE {
|
virtual bool finalizeInBackground(Value priv) const MOZ_OVERRIDE {
|
||||||
@@ -86,9 +84,11 @@ class CPOWProxyHandler : public BaseProxyHandler
|
|||||||
virtual const char* className(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
|
virtual const char* className(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
|
||||||
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
|
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
static const char family;
|
||||||
static const CPOWProxyHandler singleton;
|
static const CPOWProxyHandler singleton;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char CPOWProxyHandler::family = 0;
|
||||||
const CPOWProxyHandler CPOWProxyHandler::singleton;
|
const CPOWProxyHandler CPOWProxyHandler::singleton;
|
||||||
|
|
||||||
#define FORWARD(call, args) \
|
#define FORWARD(call, args) \
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ JS_IsDeadWrapper(JSObject *obj)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj->as<ProxyObject>().handler()->family() == &DeadObjectProxy::sDeadObjectFamily;
|
return obj->as<ProxyObject>().handler()->family() == &DeadObjectProxy::family;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -797,6 +797,7 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
|||||||
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) const MOZ_OVERRIDE;
|
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) const MOZ_OVERRIDE;
|
||||||
virtual bool isScripted() const MOZ_OVERRIDE { return true; }
|
virtual bool isScripted() const MOZ_OVERRIDE { return true; }
|
||||||
|
|
||||||
|
static const char family;
|
||||||
static const ScriptedIndirectProxyHandler singleton;
|
static const ScriptedIndirectProxyHandler singleton;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -818,10 +819,10 @@ static const Class CallConstructHolder = {
|
|||||||
} /* anonymous namespace */
|
} /* anonymous namespace */
|
||||||
|
|
||||||
// This variable exists solely to provide a unique address for use as an identifier.
|
// This variable exists solely to provide a unique address for use as an identifier.
|
||||||
static const char sScriptedIndirectProxyHandlerFamily = 0;
|
const char ScriptedIndirectProxyHandler::family = 0;
|
||||||
|
|
||||||
ScriptedIndirectProxyHandler::ScriptedIndirectProxyHandler()
|
ScriptedIndirectProxyHandler::ScriptedIndirectProxyHandler()
|
||||||
: BaseProxyHandler(&sScriptedIndirectProxyHandlerFamily)
|
: BaseProxyHandler(&family)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,6 +1119,7 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
|
|||||||
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
|
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
|
||||||
virtual bool isScripted() const MOZ_OVERRIDE { return true; }
|
virtual bool isScripted() const MOZ_OVERRIDE { return true; }
|
||||||
|
|
||||||
|
static const char family;
|
||||||
static const ScriptedDirectProxyHandler singleton;
|
static const ScriptedDirectProxyHandler singleton;
|
||||||
|
|
||||||
// The "proxy extra" slot index in which the handler is stored. Revocable proxies need to set
|
// The "proxy extra" slot index in which the handler is stored. Revocable proxies need to set
|
||||||
@@ -1128,9 +1130,6 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
|
|||||||
static const int REVOKE_SLOT = 0;
|
static const int REVOKE_SLOT = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This variable exists solely to provide a unique address for use as an identifier.
|
|
||||||
static const char sScriptedDirectProxyHandlerFamily = 0;
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
IsDataDescriptor(const PropertyDescriptor &desc)
|
IsDataDescriptor(const PropertyDescriptor &desc)
|
||||||
{
|
{
|
||||||
@@ -1389,7 +1388,7 @@ ArrayToIdVector(JSContext *cx, HandleObject proxy, HandleObject target, HandleVa
|
|||||||
}
|
}
|
||||||
|
|
||||||
ScriptedDirectProxyHandler::ScriptedDirectProxyHandler()
|
ScriptedDirectProxyHandler::ScriptedDirectProxyHandler()
|
||||||
: DirectProxyHandler(&sScriptedDirectProxyHandlerFamily)
|
: DirectProxyHandler(&family)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2208,6 +2207,7 @@ ScriptedDirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const C
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char ScriptedDirectProxyHandler::family = 0;
|
||||||
const ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
|
const ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
|
||||||
|
|
||||||
#define INVOKE_ON_PROTOTYPE(cx, handler, proxy, protoCall) \
|
#define INVOKE_ON_PROTOTYPE(cx, handler, proxy, protoCall) \
|
||||||
|
|||||||
@@ -87,6 +87,14 @@ class JS_FRIEND_API(Wrapper);
|
|||||||
*/
|
*/
|
||||||
class JS_FRIEND_API(BaseProxyHandler)
|
class JS_FRIEND_API(BaseProxyHandler)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Sometimes it's desirable to designate groups of proxy handlers as "similar".
|
||||||
|
* For this, we use the notion of a "family": A consumer-provided opaque pointer
|
||||||
|
* that designates the larger group to which this proxy belongs.
|
||||||
|
*
|
||||||
|
* If it will never be important to differentiate this proxy from others as
|
||||||
|
* part of a distinct group, nullptr may be used instead.
|
||||||
|
*/
|
||||||
const void *mFamily;
|
const void *mFamily;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace js::gc;
|
using namespace js::gc;
|
||||||
|
|
||||||
const char js::sWrapperFamily = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper forwards this call directly to the wrapped object for efficiency
|
* Wrapper forwards this call directly to the wrapped object for efficiency
|
||||||
* and transparency. In particular, the hint is needed to properly stringify
|
* and transparency. In particular, the hint is needed to properly stringify
|
||||||
@@ -131,7 +129,7 @@ js::IsCrossCompartmentWrapper(JSObject *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Wrapper::Wrapper(unsigned flags, bool hasPrototype, bool hasSecurityPolicy)
|
Wrapper::Wrapper(unsigned flags, bool hasPrototype, bool hasSecurityPolicy)
|
||||||
: DirectProxyHandler(&sWrapperFamily, hasPrototype, hasSecurityPolicy),
|
: DirectProxyHandler(&family, hasPrototype, hasSecurityPolicy),
|
||||||
mFlags(flags)
|
mFlags(flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -140,6 +138,7 @@ Wrapper::~Wrapper()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char Wrapper::family = 0;
|
||||||
const Wrapper Wrapper::singleton((unsigned)0);
|
const Wrapper Wrapper::singleton((unsigned)0);
|
||||||
const Wrapper Wrapper::singletonWithPrototype((unsigned)0, true);
|
const Wrapper Wrapper::singletonWithPrototype((unsigned)0, true);
|
||||||
JSObject *Wrapper::defaultProto = TaggedProto::LazyProto;
|
JSObject *Wrapper::defaultProto = TaggedProto::LazyProto;
|
||||||
@@ -748,7 +747,7 @@ template class js::SecurityWrapper<Wrapper>;
|
|||||||
template class js::SecurityWrapper<CrossCompartmentWrapper>;
|
template class js::SecurityWrapper<CrossCompartmentWrapper>;
|
||||||
|
|
||||||
DeadObjectProxy::DeadObjectProxy()
|
DeadObjectProxy::DeadObjectProxy()
|
||||||
: BaseProxyHandler(&sDeadObjectFamily)
|
: BaseProxyHandler(&family)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,8 +884,8 @@ DeadObjectProxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandle
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char DeadObjectProxy::family = 0;
|
||||||
const DeadObjectProxy DeadObjectProxy::singleton;
|
const DeadObjectProxy DeadObjectProxy::singleton;
|
||||||
const char DeadObjectProxy::sDeadObjectFamily = 0;
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::IsDeadProxyObject(JSObject *obj)
|
js::IsDeadProxyObject(JSObject *obj)
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
|||||||
|
|
||||||
virtual bool finalizeInBackground(Value priv) const MOZ_OVERRIDE;
|
virtual bool finalizeInBackground(Value priv) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
static const char family;
|
||||||
static const Wrapper singleton;
|
static const Wrapper singleton;
|
||||||
static const Wrapper singletonWithPrototype;
|
static const Wrapper singletonWithPrototype;
|
||||||
|
|
||||||
@@ -207,9 +208,6 @@ typedef SecurityWrapper<CrossCompartmentWrapper> CrossCompartmentSecurityWrapper
|
|||||||
class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
|
class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// This variable exists solely to provide a unique address for use as an identifier.
|
|
||||||
static const char sDeadObjectFamily;
|
|
||||||
|
|
||||||
explicit DeadObjectProxy();
|
explicit DeadObjectProxy();
|
||||||
|
|
||||||
/* ES5 Harmony fundamental wrapper traps. */
|
/* ES5 Harmony fundamental wrapper traps. */
|
||||||
@@ -243,6 +241,7 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
|
|||||||
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
|
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
|
||||||
MutableHandleObject protop) const MOZ_OVERRIDE;
|
MutableHandleObject protop) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
static const char family;
|
||||||
static const DeadObjectProxy singleton;
|
static const DeadObjectProxy singleton;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,15 +249,10 @@ extern JSObject *
|
|||||||
TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj,
|
TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj,
|
||||||
HandleObject parent);
|
HandleObject parent);
|
||||||
|
|
||||||
// Proxy family for wrappers. Public so that IsWrapper() can be fully inlined by
|
|
||||||
// jsfriendapi users.
|
|
||||||
// This variable exists solely to provide a unique address for use as an identifier.
|
|
||||||
extern JS_FRIEND_DATA(const char) sWrapperFamily;
|
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
IsWrapper(JSObject *obj)
|
IsWrapper(JSObject *obj)
|
||||||
{
|
{
|
||||||
return IsProxy(obj) && GetProxyHandler(obj)->family() == &sWrapperFamily;
|
return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a JSObject, returns that object stripped of wrappers. If
|
// Given a JSObject, returns that object stripped of wrappers. If
|
||||||
|
|||||||
@@ -1323,7 +1323,7 @@ class DebugScopeProxy : public BaseProxyHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static int family;
|
static const char family;
|
||||||
static const DebugScopeProxy singleton;
|
static const DebugScopeProxy singleton;
|
||||||
|
|
||||||
DebugScopeProxy() : BaseProxyHandler(&family) {}
|
DebugScopeProxy() : BaseProxyHandler(&family) {}
|
||||||
@@ -1592,7 +1592,7 @@ class DebugScopeProxy : public BaseProxyHandler
|
|||||||
|
|
||||||
} /* anonymous namespace */
|
} /* anonymous namespace */
|
||||||
|
|
||||||
int DebugScopeProxy::family = 0;
|
const char DebugScopeProxy::family = 0;
|
||||||
const DebugScopeProxy DebugScopeProxy::singleton;
|
const DebugScopeProxy DebugScopeProxy::singleton;
|
||||||
|
|
||||||
/* static */ DebugScopeObject *
|
/* static */ DebugScopeObject *
|
||||||
|
|||||||
Reference in New Issue
Block a user