mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 947014 - Allow callers of Wrapper::New to specify a prototype. (r=bholley)
This commit is contained in:
parent
e131d468b7
commit
232ac6947a
@ -448,12 +448,6 @@ class MOZ_STACK_CLASS ProxyOptions {
|
||||
const Class *clasp_;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions {
|
||||
public:
|
||||
WrapperOptions() : ProxyOptions(false, nullptr)
|
||||
{}
|
||||
};
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
NewProxyObject(JSContext *cx, BaseProxyHandler *handler, HandleValue priv,
|
||||
JSObject *proto, JSObject *parent, const ProxyOptions &options = ProxyOptions());
|
||||
|
@ -53,7 +53,7 @@ Wrapper::New(JSContext *cx, JSObject *obj, JSObject *parent, Wrapper *handler,
|
||||
opts.ref().selectDefaultClass(obj->isCallable());
|
||||
options = opts.addr();
|
||||
}
|
||||
return NewProxyObject(cx, handler, priv, TaggedProto::LazyProto, parent, *options);
|
||||
return NewProxyObject(cx, handler, priv, options->proto(), parent, *options);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
@ -142,6 +142,7 @@ Wrapper::~Wrapper()
|
||||
|
||||
Wrapper Wrapper::singleton((unsigned)0);
|
||||
Wrapper Wrapper::singletonWithPrototype((unsigned)0, true);
|
||||
JSObject *Wrapper::defaultProto = TaggedProto::LazyProto;
|
||||
|
||||
/* Compartments. */
|
||||
|
||||
|
@ -15,6 +15,37 @@ namespace js {
|
||||
|
||||
class DummyFrameGuard;
|
||||
|
||||
/*
|
||||
* Helper for Wrapper::New default options.
|
||||
*
|
||||
* Callers of Wrapper::New() who wish to specify a prototype for the created
|
||||
* Wrapper, *MUST* construct a WrapperOptions with a JSContext.
|
||||
*/
|
||||
class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions {
|
||||
public:
|
||||
WrapperOptions() : ProxyOptions(false, nullptr),
|
||||
proto_()
|
||||
{}
|
||||
|
||||
WrapperOptions(JSContext *cx) : ProxyOptions(false, nullptr),
|
||||
proto_()
|
||||
{
|
||||
proto_.construct(cx);
|
||||
}
|
||||
|
||||
JSObject *proto() const {
|
||||
return proto_.empty() ? Wrapper::defaultProto : proto_.ref();
|
||||
}
|
||||
WrapperOptions &setProto(JSObject *protoArg) {
|
||||
JS_ASSERT(!proto_.empty());
|
||||
proto_.ref() = protoArg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
mozilla::Maybe<JS::RootedObject> proto_;
|
||||
};
|
||||
|
||||
/*
|
||||
* A wrapper is a proxy with a target object to which it generally forwards
|
||||
* operations, but may restrict access to certain operations or instrument
|
||||
@ -60,6 +91,8 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
||||
|
||||
static Wrapper singleton;
|
||||
static Wrapper singletonWithPrototype;
|
||||
|
||||
static JSObject *defaultProto;
|
||||
};
|
||||
|
||||
/* Base class for all cross compartment wrapper handlers. */
|
||||
|
@ -3764,34 +3764,6 @@ ThisFilename(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal class for testing hasPrototype easily.
|
||||
* Uses passed in prototype instead of target's.
|
||||
*/
|
||||
class WrapperWithProto : public Wrapper
|
||||
{
|
||||
public:
|
||||
explicit WrapperWithProto(unsigned flags)
|
||||
: Wrapper(flags, true)
|
||||
{ }
|
||||
|
||||
static JSObject *New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
|
||||
Wrapper *handler);
|
||||
};
|
||||
|
||||
/* static */ JSObject *
|
||||
WrapperWithProto::New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
|
||||
Wrapper *handler)
|
||||
{
|
||||
JS_ASSERT(parent);
|
||||
AutoMarkInDeadZone amd(cx->zone());
|
||||
|
||||
RootedValue priv(cx, ObjectValue(*obj));
|
||||
ProxyOptions options;
|
||||
options.selectDefaultClass(obj->isCallable());
|
||||
return NewProxyObject(cx, handler, priv, proto, parent, options);
|
||||
}
|
||||
|
||||
static bool
|
||||
Wrap(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
@ -3825,9 +3797,11 @@ WrapWithProto(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
JSObject *wrapped = WrapperWithProto::New(cx, &obj.toObject(), proto.toObjectOrNull(),
|
||||
&obj.toObject().global(),
|
||||
&Wrapper::singletonWithPrototype);
|
||||
WrapperOptions options(cx);
|
||||
options.setProto(proto.toObjectOrNull());
|
||||
options.selectDefaultClass(obj.toObject().isCallable());
|
||||
JSObject *wrapped = Wrapper::New(cx, &obj.toObject(), &obj.toObject().global(),
|
||||
&Wrapper::singletonWithPrototype, &options);
|
||||
if (!wrapped)
|
||||
return false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user