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:
Jeff Walden 2016-05-03 17:29:10 -07:00
Родитель 47cde44daf
Коммит ab5f41a86c
6 изменённых файлов: 373 добавлений и 390 удалений

Просмотреть файл

@ -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());
}