author | Eric Faust <efaustbmo@gmail.com> |
Wed, 29 Jan 2014 17:20:16 -0800 | |
changeset 165900 | f6395f80b24fa7235fbfbf64f13d67339e74518a |
parent 165899 | beb52f820ac567ba0adb91c14f35429d581e64c1 |
child 165901 | d44de38ad97f2aaeb289ca3d90cd956845d39c4c |
push id | 39065 |
push user | efaustbmo@gmail.com |
push date | Thu, 30 Jan 2014 01:20:37 +0000 |
treeherder | mozilla-inbound@f6395f80b24f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bholley |
bugs | 947014 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/jsproxy.h | file | annotate | diff | comparison | revisions | |
js/src/jswrapper.cpp | file | annotate | diff | comparison | revisions | |
js/src/jswrapper.h | file | annotate | diff | comparison | revisions | |
js/src/shell/js.cpp | file | annotate | diff | comparison | revisions |
--- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -443,22 +443,16 @@ class MOZ_STACK_CLASS ProxyOptions { return setClass(classp); } private: bool singleton_; 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()); JSObject * RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv); class JS_FRIEND_API(AutoEnterPolicy)
--- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -48,17 +48,17 @@ Wrapper::New(JSContext *cx, JSObject *ob RootedValue priv(cx, ObjectValue(*obj)); mozilla::Maybe<WrapperOptions> opts; if (!options) { opts.construct(); 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 * Wrapper::Renew(JSContext *cx, JSObject *existing, JSObject *obj, Wrapper *handler) { JS_ASSERT(!obj->isCallable()); existing->as<ProxyObject>().renew(cx, handler, ObjectValue(*obj)); return existing; @@ -137,16 +137,17 @@ Wrapper::Wrapper(unsigned flags, bool ha } Wrapper::~Wrapper() { } Wrapper Wrapper::singleton((unsigned)0); Wrapper Wrapper::singletonWithPrototype((unsigned)0, true); +JSObject *Wrapper::defaultProto = TaggedProto::LazyProto; /* Compartments. */ extern JSObject * js::TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj, HandleObject wrappedProto, HandleObject parent, unsigned flags) {
--- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -11,16 +11,47 @@ #include "jsproxy.h" 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 * the trap operations 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 context. */ @@ -55,16 +86,18 @@ class JS_FRIEND_API(Wrapper) : public Di explicit Wrapper(unsigned flags, bool hasPrototype = false); virtual ~Wrapper(); virtual bool finalizeInBackground(Value priv) MOZ_OVERRIDE; static Wrapper singleton; static Wrapper singletonWithPrototype; + + static JSObject *defaultProto; }; /* Base class for all cross compartment wrapper handlers. */ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper { public: CrossCompartmentWrapper(unsigned flags, bool hasPrototype = false);
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -3759,44 +3759,16 @@ ThisFilename(JSContext *cx, unsigned arg } JSString *filename = JS_NewStringCopyZ(cx, script->filename()); if (!filename) return false; args.rval().setString(filename); 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) { jsval v = argc > 0 ? JS_ARGV(cx, vp)[0] : UndefinedValue(); if (JSVAL_IS_PRIMITIVE(v)) { JS_SET_RVAL(cx, vp, v); return true; } @@ -3820,19 +3792,21 @@ WrapWithProto(JSContext *cx, unsigned ar proto = JS_ARGV(cx, vp)[1]; } if (!obj.isObject() || !proto.isObjectOrNull()) { JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "wrapWithProto"); 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; JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(wrapped)); return true; } static JSObject *