зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1269928 - Fold DirectProxyHandler into Wrapper, which is now its only (non-test) consumer. r=efaust
--HG-- extra : rebase_source : cfe2b7aafd5867d39445815e8f732a0845d6977d
This commit is contained in:
Родитель
47cde44daf
Коммит
ab5f41a86c
|
@ -101,10 +101,8 @@ class JS_FRIEND_API(Wrapper);
|
|||
*
|
||||
* BaseProxyHandler
|
||||
* |
|
||||
* DirectProxyHandler // has a target
|
||||
* |
|
||||
* Wrapper // can be unwrapped, revealing target
|
||||
* | // (see js::CheckedUnwrap)
|
||||
* Wrapper // has a target, can be unwrapped to reveal
|
||||
* | // target (see js::CheckedUnwrap)
|
||||
* |
|
||||
* CrossCompartmentWrapper // target is in another compartment;
|
||||
* // implements membrane between compartments
|
||||
|
@ -349,81 +347,6 @@ class JS_FRIEND_API(BaseProxyHandler)
|
|||
virtual bool isScripted() const { return false; }
|
||||
};
|
||||
|
||||
/*
|
||||
* DirectProxyHandler includes a notion of a target object. All methods are
|
||||
* reimplemented such that they forward their behavior to the target. This
|
||||
* allows consumers of this class to forward to another object as transparently
|
||||
* and efficiently as possible.
|
||||
*
|
||||
* Important: If you add a method implementation here, you probably also need
|
||||
* to add an override in CrossCompartmentWrapper. If you don't, you risk
|
||||
* compartment mismatches. See bug 945826 comment 0.
|
||||
*/
|
||||
class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler
|
||||
{
|
||||
public:
|
||||
explicit MOZ_CONSTEXPR DirectProxyHandler(const void* aFamily, bool aHasPrototype = false,
|
||||
bool aHasSecurityPolicy = false)
|
||||
: BaseProxyHandler(aFamily, aHasPrototype, aHasSecurityPolicy)
|
||||
{ }
|
||||
|
||||
/* Standard internal methods. */
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool enumerate(JSContext* cx, HandleObject proxy,
|
||||
MutableHandleObject objp) const override;
|
||||
virtual bool getPrototype(JSContext* cx, HandleObject proxy,
|
||||
MutableHandleObject protop) const override;
|
||||
virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary,
|
||||
MutableHandleObject protop) const override;
|
||||
virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy,
|
||||
bool* succeeded) const override;
|
||||
virtual bool preventExtensions(JSContext* cx, HandleObject proxy,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override;
|
||||
virtual bool has(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
bool* bp) const override;
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver,
|
||||
HandleId id, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult& result) const override;
|
||||
virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
|
||||
/* SpiderMonkey extensions. */
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const override;
|
||||
virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
bool* bp) const override;
|
||||
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
|
||||
const CallArgs& args) const override;
|
||||
virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool* bp) const override;
|
||||
virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy,
|
||||
ESClassValue* classValue) const override;
|
||||
virtual bool isArray(JSContext* cx, HandleObject proxy,
|
||||
JS::IsArrayAnswer* answer) const override;
|
||||
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
||||
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
||||
unsigned indent) const override;
|
||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||
RegExpGuard* g) const override;
|
||||
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
|
||||
virtual bool isCallable(JSObject* obj) const override;
|
||||
virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const override;
|
||||
};
|
||||
|
||||
extern JS_FRIEND_DATA(const js::Class* const) ProxyClassPtr;
|
||||
|
||||
inline bool IsProxy(const JSObject* obj)
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
using namespace js;
|
||||
using namespace JS;
|
||||
|
||||
class CustomProxyHandler : public DirectProxyHandler {
|
||||
class CustomProxyHandler : public Wrapper
|
||||
{
|
||||
public:
|
||||
CustomProxyHandler() : DirectProxyHandler(nullptr) {}
|
||||
CustomProxyHandler() : Wrapper(0) {}
|
||||
|
||||
bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const override
|
||||
|
@ -31,7 +32,7 @@ class CustomProxyHandler : public DirectProxyHandler {
|
|||
ObjectOpResult& result) const override
|
||||
{
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc))
|
||||
if (!Wrapper::getPropertyDescriptor(cx, proxy, id, &desc))
|
||||
return false;
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result);
|
||||
}
|
||||
|
@ -53,8 +54,8 @@ class CustomProxyHandler : public DirectProxyHandler {
|
|||
}
|
||||
|
||||
if (ownOnly)
|
||||
return DirectProxyHandler::getOwnPropertyDescriptor(cx, proxy, id, desc);
|
||||
return DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, desc);
|
||||
return Wrapper::getOwnPropertyDescriptor(cx, proxy, id, desc);
|
||||
return Wrapper::getPropertyDescriptor(cx, proxy, id, desc);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -44,18 +44,88 @@ class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions {
|
|||
|
||||
/*
|
||||
* A wrapper is a proxy with a target object to which it generally forwards
|
||||
* operations, but may restrict access to certain operations or instrument the
|
||||
* methods in various ways. A wrapper is distinct from a Direct Proxy Handler
|
||||
* in the sense that it can be "unwrapped" in C++, exposing the underlying
|
||||
* object (Direct Proxy Handlers have an underlying target object, but don't
|
||||
* expect to expose this object via any kind of unwrapping operation). Callers
|
||||
* should be careful to avoid unwrapping security wrappers in the wrong
|
||||
* operations, but may restrict access to certain operations or augment those
|
||||
* operations in various ways.
|
||||
*
|
||||
* A wrapper can be "unwrapped" in C++, exposing the underlying object.
|
||||
* Callers should be careful to avoid unwrapping security wrappers in the wrong
|
||||
* context.
|
||||
*
|
||||
* Important: If you add a method implementation here, you probably also need
|
||||
* to add an override in CrossCompartmentWrapper. If you don't, you risk
|
||||
* compartment mismatches. See bug 945826 comment 0.
|
||||
*/
|
||||
class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
||||
class JS_FRIEND_API(Wrapper) : public BaseProxyHandler
|
||||
{
|
||||
unsigned mFlags;
|
||||
|
||||
public:
|
||||
explicit MOZ_CONSTEXPR Wrapper(unsigned aFlags, bool aHasPrototype = false,
|
||||
bool aHasSecurityPolicy = false)
|
||||
: BaseProxyHandler(&family, aHasPrototype, aHasSecurityPolicy),
|
||||
mFlags(aFlags)
|
||||
{ }
|
||||
|
||||
virtual bool finalizeInBackground(Value priv) const override;
|
||||
|
||||
/* Standard internal methods. */
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool enumerate(JSContext* cx, HandleObject proxy,
|
||||
MutableHandleObject objp) const override;
|
||||
virtual bool getPrototype(JSContext* cx, HandleObject proxy,
|
||||
MutableHandleObject protop) const override;
|
||||
virtual bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary,
|
||||
MutableHandleObject protop) const override;
|
||||
virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy,
|
||||
bool* succeeded) const override;
|
||||
virtual bool preventExtensions(JSContext* cx, HandleObject proxy,
|
||||
ObjectOpResult& result) const override;
|
||||
virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override;
|
||||
virtual bool has(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
bool* bp) const override;
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver,
|
||||
HandleId id, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult& result) const override;
|
||||
virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
|
||||
/* SpiderMonkey extensions. */
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const override;
|
||||
virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
bool* bp) const override;
|
||||
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
|
||||
const CallArgs& args) const override;
|
||||
virtual bool hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool* bp) const override;
|
||||
virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy,
|
||||
ESClassValue* classValue) const override;
|
||||
virtual bool isArray(JSContext* cx, HandleObject proxy,
|
||||
JS::IsArrayAnswer* answer) const override;
|
||||
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
||||
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
||||
unsigned indent) const override;
|
||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||
RegExpGuard* g) const override;
|
||||
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy,
|
||||
MutableHandleValue vp) const override;
|
||||
virtual bool isCallable(JSObject* obj) const override;
|
||||
virtual bool isConstructor(JSObject* obj) const override;
|
||||
virtual JSObject* weakmapKeyDelegate(JSObject* proxy) const override;
|
||||
|
||||
public:
|
||||
using BaseProxyHandler::Action;
|
||||
|
||||
|
@ -77,15 +147,6 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
|||
return mFlags;
|
||||
}
|
||||
|
||||
explicit MOZ_CONSTEXPR Wrapper(unsigned aFlags, bool aHasPrototype = false,
|
||||
bool aHasSecurityPolicy = false)
|
||||
: DirectProxyHandler(&family, aHasPrototype, aHasSecurityPolicy),
|
||||
mFlags(aFlags)
|
||||
{ }
|
||||
|
||||
virtual bool finalizeInBackground(Value priv) const override;
|
||||
virtual bool isConstructor(JSObject* obj) const override;
|
||||
|
||||
static const char family;
|
||||
static const Wrapper singleton;
|
||||
static const Wrapper singletonWithPrototype;
|
||||
|
|
|
@ -303,7 +303,6 @@ UNIFIED_SOURCES += [
|
|||
'proxy/BaseProxyHandler.cpp',
|
||||
'proxy/CrossCompartmentWrapper.cpp',
|
||||
'proxy/DeadObjectProxy.cpp',
|
||||
'proxy/DirectProxyHandler.cpp',
|
||||
'proxy/OpaqueCrossCompartmentWrapper.cpp',
|
||||
'proxy/Proxy.cpp',
|
||||
'proxy/ScriptedDirectProxyHandler.cpp',
|
||||
|
|
|
@ -13,264 +13,4 @@
|
|||
|
||||
using namespace js;
|
||||
|
||||
bool
|
||||
DirectProxyHandler::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET | SET | GET_PROPERTY_DESCRIPTOR);
|
||||
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyDescriptor(cx, target, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET | SET | GET_PROPERTY_DESCRIPTOR);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetOwnPropertyDescriptor(cx, target, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return DefineProperty(cx, target, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyKeys(cx, target, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &props);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::delete_(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return DeleteProperty(cx, target, id, result);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
|
||||
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetIterator(cx, target, 0, objp);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::call(JSContext* cx, HandleObject proxy, const CallArgs& args) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
|
||||
RootedValue target(cx, proxy->as<ProxyObject>().private_());
|
||||
|
||||
InvokeArgs iargs(cx);
|
||||
if (!FillArgumentsFromArraylike(cx, iargs, args))
|
||||
return false;
|
||||
|
||||
return js::Call(cx, target, args.thisv(), iargs, args.rval());
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
|
||||
|
||||
RootedValue target(cx, proxy->as<ProxyObject>().private_());
|
||||
if (!IsConstructor(target)) {
|
||||
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, target, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
ConstructArgs cargs(cx);
|
||||
if (!FillArgumentsFromArraylike(cx, cargs, args))
|
||||
return false;
|
||||
|
||||
RootedObject obj(cx);
|
||||
if (!Construct(cx, target, cargs, args.newTarget(), &obj))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
|
||||
const CallArgs& args) const
|
||||
{
|
||||
args.setThis(ObjectValue(*args.thisv().toObject().as<ProxyObject>().target()));
|
||||
if (!test(args.thisv())) {
|
||||
ReportIncompatible(cx, args);
|
||||
return false;
|
||||
}
|
||||
|
||||
return CallNativeImpl(cx, impl, args);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool* bp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return HasInstance(cx, target, v, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPrototype(cx, target, protop);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto,
|
||||
ObjectOpResult& result) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetPrototype(cx, target, proto, result);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy,
|
||||
bool* isOrdinary, MutableHandleObject protop) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPrototypeIfOrdinary(cx, target, isOrdinary, protop);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetImmutablePrototype(cx, target, succeeded);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::preventExtensions(JSContext* cx, HandleObject proxy, ObjectOpResult& result) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return PreventExtensions(cx, target, result);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return IsExtensible(cx, target, extensible);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::getBuiltinClass(JSContext* cx, HandleObject proxy,
|
||||
ESClassValue* classValue) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetBuiltinClass(cx, target, classValue);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return IsArray(cx, target, answer);
|
||||
}
|
||||
|
||||
const char*
|
||||
DirectProxyHandler::className(JSContext* cx, HandleObject proxy) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetObjectClassName(cx, target);
|
||||
}
|
||||
|
||||
JSString*
|
||||
DirectProxyHandler::fun_toString(JSContext* cx, HandleObject proxy,
|
||||
unsigned indent) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return fun_toStringHelper(cx, target, indent);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||
RegExpGuard* g) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return RegExpToShared(cx, target, g);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return Unbox(cx, target, vp);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
DirectProxyHandler::weakmapKeyDelegate(JSObject* proxy) const
|
||||
{
|
||||
return UncheckedUnwrap(proxy);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return HasProperty(cx, target, id, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return HasOwnProperty(cx, target, id, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleValue receiver,
|
||||
HandleId id, MutableHandleValue vp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetProperty(cx, target, receiver, id, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetProperty(cx, target, id, v, receiver, result);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyKeys(cx, target, JSITER_OWNONLY, &props);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::isCallable(JSObject* obj) const
|
||||
{
|
||||
JSObject * target = obj->as<ProxyObject>().target();
|
||||
return target->isCallable();
|
||||
}
|
||||
|
|
|
@ -9,13 +9,298 @@
|
|||
#include "jsexn.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "js/Proxy.h"
|
||||
#include "vm/ErrorObject.h"
|
||||
#include "vm/ProxyObject.h"
|
||||
#include "vm/WrapperObject.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
bool
|
||||
Wrapper::finalizeInBackground(Value priv) const
|
||||
{
|
||||
if (!priv.isObject())
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Make the 'background-finalized-ness' of the wrapper the same as the
|
||||
* wrapped object, to allow transplanting between them.
|
||||
*
|
||||
* If the wrapped object is in the nursery then we know it doesn't have a
|
||||
* finalizer, and so background finalization is ok.
|
||||
*/
|
||||
if (IsInsideNursery(&priv.toObject()))
|
||||
return true;
|
||||
return IsBackgroundFinalized(priv.toObject().asTenured().getAllocKind());
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET | SET | GET_PROPERTY_DESCRIPTOR);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetOwnPropertyDescriptor(cx, target, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc, ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return DefineProperty(cx, target, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::ownPropertyKeys(JSContext* cx, HandleObject proxy, AutoIdVector& props) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyKeys(cx, target, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &props);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::delete_(JSContext* cx, HandleObject proxy, HandleId id, ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return DeleteProperty(cx, target, id, result);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
|
||||
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetIterator(cx, target, 0, objp);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPrototype(cx, target, protop);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto,
|
||||
ObjectOpResult& result) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetPrototype(cx, target, proto, result);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy,
|
||||
bool* isOrdinary, MutableHandleObject protop) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPrototypeIfOrdinary(cx, target, isOrdinary, protop);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetImmutablePrototype(cx, target, succeeded);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::preventExtensions(JSContext* cx, HandleObject proxy, ObjectOpResult& result) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return PreventExtensions(cx, target, result);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return IsExtensible(cx, target, extensible);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return HasProperty(cx, target, id, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::get(JSContext* cx, HandleObject proxy, HandleValue receiver, HandleId id,
|
||||
MutableHandleValue vp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetProperty(cx, target, receiver, id, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver,
|
||||
ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetProperty(cx, target, id, v, receiver, result);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::call(JSContext* cx, HandleObject proxy, const CallArgs& args) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
|
||||
RootedValue target(cx, proxy->as<ProxyObject>().private_());
|
||||
|
||||
InvokeArgs iargs(cx);
|
||||
if (!FillArgumentsFromArraylike(cx, iargs, args))
|
||||
return false;
|
||||
|
||||
return js::Call(cx, target, args.thisv(), iargs, args.rval());
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
|
||||
|
||||
RootedValue target(cx, proxy->as<ProxyObject>().private_());
|
||||
if (!IsConstructor(target)) {
|
||||
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, target, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
ConstructArgs cargs(cx);
|
||||
if (!FillArgumentsFromArraylike(cx, cargs, args))
|
||||
return false;
|
||||
|
||||
RootedObject obj(cx);
|
||||
if (!Construct(cx, target, cargs, args.newTarget(), &obj))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET | SET | GET_PROPERTY_DESCRIPTOR);
|
||||
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyDescriptor(cx, target, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return HasOwnProperty(cx, target, id, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetPropertyKeys(cx, target, JSITER_OWNONLY, &props);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
|
||||
const CallArgs& args) const
|
||||
{
|
||||
args.setThis(ObjectValue(*args.thisv().toObject().as<ProxyObject>().target()));
|
||||
if (!test(args.thisv())) {
|
||||
ReportIncompatible(cx, args);
|
||||
return false;
|
||||
}
|
||||
|
||||
return CallNativeImpl(cx, impl, args);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool* bp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return HasInstance(cx, target, v, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::getBuiltinClass(JSContext* cx, HandleObject proxy, ESClassValue* classValue) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetBuiltinClass(cx, target, classValue);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return IsArray(cx, target, answer);
|
||||
}
|
||||
|
||||
const char*
|
||||
Wrapper::className(JSContext* cx, HandleObject proxy) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return GetObjectClassName(cx, target);
|
||||
}
|
||||
|
||||
JSString*
|
||||
Wrapper::fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return fun_toStringHelper(cx, target, indent);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return RegExpToShared(cx, target, g);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const
|
||||
{
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return Unbox(cx, target, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::isCallable(JSObject* obj) const
|
||||
{
|
||||
JSObject * target = obj->as<ProxyObject>().target();
|
||||
return target->isCallable();
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::isConstructor(JSObject* obj) const
|
||||
{
|
||||
// For now, all wrappers are constructable if they are callable. We will want to eventually
|
||||
// decouple this behavior, but none of the Wrapper infrastructure is currently prepared for
|
||||
// that.
|
||||
return isCallable(obj);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Wrapper::weakmapKeyDelegate(JSObject* proxy) const
|
||||
{
|
||||
return UncheckedUnwrap(proxy);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Wrapper::New(JSContext* cx, JSObject* obj, const Wrapper* handler,
|
||||
const WrapperOptions& options)
|
||||
|
@ -45,15 +330,6 @@ Wrapper::wrappedObject(JSObject* wrapper)
|
|||
return wrapper->as<ProxyObject>().target();
|
||||
}
|
||||
|
||||
bool
|
||||
Wrapper::isConstructor(JSObject* obj) const
|
||||
{
|
||||
// For now, all wrappers are constructable if they are callable. We will want to eventually
|
||||
// decouple this behavior, but none of the Wrapper infrastructure is currently prepared for
|
||||
// that.
|
||||
return isCallable(obj);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject*)
|
||||
js::UncheckedUnwrap(JSObject* wrapped, bool stopAtWindowProxy, unsigned* flagsp)
|
||||
{
|
||||
|
@ -67,8 +343,8 @@ js::UncheckedUnwrap(JSObject* wrapped, bool stopAtWindowProxy, unsigned* flagsp)
|
|||
flags |= Wrapper::wrapperHandler(wrapped)->flags();
|
||||
wrapped = wrapped->as<ProxyObject>().private_().toObjectOrNull();
|
||||
|
||||
// This can be called from DirectProxyHandler::weakmapKeyDelegate() on a
|
||||
// wrapper whose referent has been moved while it is still unmarked.
|
||||
// This can be called from Wrapper::weakmapKeyDelegate() on a wrapper
|
||||
// whose referent has been moved while it is still unmarked.
|
||||
if (wrapped)
|
||||
wrapped = MaybeForwarded(wrapped);
|
||||
}
|
||||
|
@ -108,7 +384,7 @@ JSObject* Wrapper::defaultProto = TaggedProto::LazyProto;
|
|||
|
||||
/* Compartments. */
|
||||
|
||||
extern JSObject*
|
||||
JSObject*
|
||||
js::TransparentObjectWrapper(JSContext* cx, HandleObject existing, HandleObject obj)
|
||||
{
|
||||
// Allow wrapping outer window proxies.
|
||||
|
@ -137,20 +413,3 @@ ErrorCopier::~ErrorCopier()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Wrapper::finalizeInBackground(Value priv) const
|
||||
{
|
||||
if (!priv.isObject())
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Make the 'background-finalized-ness' of the wrapper the same as the
|
||||
* wrapped object, to allow transplanting between them.
|
||||
*
|
||||
* If the wrapped object is in the nursery then we know it doesn't have a
|
||||
* finalizer, and so background finalization is ok.
|
||||
*/
|
||||
if (IsInsideNursery(&priv.toObject()))
|
||||
return true;
|
||||
return IsBackgroundFinalized(priv.toObject().asTenured().getAllocKind());
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче