diff -r 981eaf7b3333 dom/base/nsGlobalWindow.cpp --- a/dom/base/nsGlobalWindow.cpp Tue May 22 21:42:21 2012 +0200 +++ b/dom/base/nsGlobalWindow.cpp Tue May 29 23:55:40 2012 +0200 @@ -563,20 +563,20 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWind {} nsPIDOMWindow::~nsPIDOMWindow() {} //***************************************************************************** // nsOuterWindowProxy: Outer Window Proxy //***************************************************************************** -class nsOuterWindowProxy : public js::Wrapper +class nsOuterWindowProxy : public js::DirectWrapper { public: - nsOuterWindowProxy() : js::Wrapper(0) {} + nsOuterWindowProxy() : js::DirectWrapper(0) {} virtual bool isOuterWindow() { return true; } JSString *obj_toString(JSContext *cx, JSObject *wrapper); void finalize(JSFreeOp *fop, JSObject *proxy); static nsOuterWindowProxy singleton; diff -r 981eaf7b3333 js/src/jsapi-tests/testBug604087.cpp --- a/js/src/jsapi-tests/testBug604087.cpp Tue May 22 21:42:21 2012 +0200 +++ b/js/src/jsapi-tests/testBug604087.cpp Tue May 29 23:55:40 2012 +0200 @@ -7,19 +7,19 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "tests.h" #include "jsobj.h" #include "jswrapper.h" -struct OuterWrapper : js::Wrapper +struct OuterWrapper : js::DirectWrapper { - OuterWrapper() : Wrapper(0) {} + OuterWrapper() : DirectWrapper(0) {} virtual bool isOuterWindow() { return true; } static OuterWrapper singleton; }; diff -r 981eaf7b3333 js/src/jsprvtd.h --- a/js/src/jsprvtd.h Tue May 22 21:42:21 2012 +0200 +++ b/js/src/jsprvtd.h Tue May 29 23:55:40 2012 +0200 @@ -145,17 +145,17 @@ class TokenStream; struct Token; struct TokenPos; struct TokenPtr; struct TreeContext; class UpvarCookie; class Proxy; class BaseProxyHandler; -class Wrapper; +class DirectWrapper; class CrossCompartmentWrapper; class TempAllocPolicy; class RuntimeAllocPolicy; class GlobalObject; template isWrapper() && !JS_UNLIKELY(stopAtOuter && wrapped->getClass()->ext.innerObject)) { - flags |= static_cast(GetProxyHandler(wrapped))->flags(); + flags |= AbstractWrapper::wrapperHandler(wrapped)->flags(); wrapped = GetProxyPrivate(wrapped).toObjectOrNull(); } if (flagsp) *flagsp = flags; return wrapped; } JS_FRIEND_API(JSObject *) @@ -78,21 +78,21 @@ js::IsCrossCompartmentWrapper(const JSOb } AbstractWrapper::AbstractWrapper(unsigned flags) : IndirectProxyHandler(&sWrapperFamily), mFlags(flags) { } -Wrapper::Wrapper(unsigned flags) : AbstractWrapper(flags) +DirectWrapper::DirectWrapper(unsigned flags) : AbstractWrapper(flags) { } -Wrapper::~Wrapper() +DirectWrapper::~DirectWrapper() { } #define CHECKED(op, act) \ JS_BEGIN_MACRO \ bool status; \ if (!enter(cx, wrapper, id, act, &status)) \ return status; \ @@ -153,113 +153,113 @@ AbstractWrapper::enumerate(JSContext *cx static bool Cond(JSBool b, bool *bp) { *bp = !!b; return true; } bool -Wrapper::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) +DirectWrapper::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) { *bp = false; // default result if we refuse to perform this action JSBool found; GET(JS_HasPropertyById(cx, wrappedObject(wrapper), id, &found) && Cond(found, bp)); } bool -Wrapper::hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) +DirectWrapper::hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) { *bp = false; // default result if we refuse to perform this action PropertyDescriptor desc; JSObject *wobj = wrappedObject(wrapper); GET(JS_GetPropertyDescriptorById(cx, wobj, id, JSRESOLVE_QUALIFIED, &desc) && Cond(desc.obj == wobj, bp)); } bool -Wrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) +DirectWrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) { vp->setUndefined(); // default result if we refuse to perform this action GET(wrappedObject(wrapper)->getGeneric(cx, RootedVarObject(cx, receiver), RootedVarId(cx, id), vp)); } bool -Wrapper::set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict, +DirectWrapper::set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict, Value *vp) { SET(wrappedObject(wrapper)->setGeneric(cx, RootedVarId(cx, id), vp, strict)); } bool -Wrapper::keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) +DirectWrapper::keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) { // if we refuse to perform this action, props remains empty const jsid id = JSID_VOID; GET(GetPropertyNames(cx, wrappedObject(wrapper), JSITER_OWNONLY, &props)); } bool -Wrapper::iterate(JSContext *cx, JSObject *wrapper, unsigned flags, Value *vp) +DirectWrapper::iterate(JSContext *cx, JSObject *wrapper, unsigned flags, Value *vp) { vp->setUndefined(); // default result if we refuse to perform this action const jsid id = JSID_VOID; GET(GetIterator(cx, RootedVarObject(cx, wrappedObject(wrapper)), flags, vp)); } bool -Wrapper::call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp) +DirectWrapper::call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp) { vp->setUndefined(); // default result if we refuse to perform this action const jsid id = JSID_VOID; CHECKED(IndirectProxyHandler::call(cx, wrapper, argc, vp), CALL); } bool -Wrapper::construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *vp) +DirectWrapper::construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *vp) { vp->setUndefined(); // default result if we refuse to perform this action const jsid id = JSID_VOID; GET(IndirectProxyHandler::construct(cx, wrapper, argc, argv, vp)); } bool -Wrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) +DirectWrapper::nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) { const jsid id = JSID_VOID; CHECKED(IndirectProxyHandler::nativeCall(cx, wrapper, clasp, native, args), CALL); } bool -Wrapper::hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) +DirectWrapper::hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) { *bp = false; // default result if we refuse to perform this action const jsid id = JSID_VOID; GET(IndirectProxyHandler::hasInstance(cx, wrapper, vp, bp)); } JSString * -Wrapper::obj_toString(JSContext *cx, JSObject *wrapper) +DirectWrapper::obj_toString(JSContext *cx, JSObject *wrapper) { bool status; if (!enter(cx, wrapper, JSID_VOID, GET, &status)) { if (status) { // Perform some default behavior that doesn't leak any information. return JS_NewStringCopyZ(cx, "[object Object]"); } return NULL; } JSString *str = IndirectProxyHandler::obj_toString(cx, wrapper); leave(cx, wrapper); return str; } JSString * -Wrapper::fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) +DirectWrapper::fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) { bool status; if (!enter(cx, wrapper, JSID_VOID, GET, &status)) { if (status) { // Perform some default behavior that doesn't leak any information. if (wrapper->isCallable()) return JS_NewStringCopyZ(cx, "function () {\n [native code]\n}"); js::Value v = ObjectValue(*wrapper); @@ -293,20 +293,21 @@ AbstractWrapper::enter(JSContext *cx, JS return true; } void AbstractWrapper::leave(JSContext *cx, JSObject *wrapper) { } -Wrapper Wrapper::singleton((unsigned)0); +DirectWrapper DirectWrapper::singleton((unsigned)0); JSObject * -Wrapper::New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, Wrapper *handler) +DirectWrapper::New(JSContext *cx, JSObject *obj, JSObject *proto, + JSObject *parent, Wrapper *handler) { JS_ASSERT(parent); #if JS_HAS_XML_SUPPORT if (obj->isXML()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WRAP_XML_OBJECT); return NULL; } #endif @@ -419,17 +420,17 @@ ErrorCopier::~ErrorCopier() cx->setPendingException(ObjectValue(*copyobj)); } } } /* Cross compartment wrappers. */ CrossCompartmentWrapper::CrossCompartmentWrapper(unsigned flags) - : Wrapper(CROSS_COMPARTMENT | flags) + : DirectWrapper(CROSS_COMPARTMENT | flags) { } CrossCompartmentWrapper::~CrossCompartmentWrapper() { } #define PIERCE(cx, wrapper, mode, pre, op, post) \ @@ -445,115 +446,115 @@ CrossCompartmentWrapper::~CrossCompartme #define NOTHING (true) bool CrossCompartmentWrapper::getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, PropertyDescriptor *desc) { PIERCE(cx, wrapper, set ? SET : GET, call.destination->wrapId(cx, &id), - Wrapper::getPropertyDescriptor(cx, wrapper, id, set, desc), + DirectWrapper::getPropertyDescriptor(cx, wrapper, id, set, desc), call.origin->wrap(cx, desc)); } bool CrossCompartmentWrapper::getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, PropertyDescriptor *desc) { PIERCE(cx, wrapper, set ? SET : GET, call.destination->wrapId(cx, &id), - Wrapper::getOwnPropertyDescriptor(cx, wrapper, id, set, desc), + DirectWrapper::getOwnPropertyDescriptor(cx, wrapper, id, set, desc), call.origin->wrap(cx, desc)); } bool CrossCompartmentWrapper::defineProperty(JSContext *cx, JSObject *wrapper, jsid id, PropertyDescriptor *desc) { AutoPropertyDescriptorRooter desc2(cx, desc); PIERCE(cx, wrapper, SET, call.destination->wrapId(cx, &id) && call.destination->wrap(cx, &desc2), - Wrapper::defineProperty(cx, wrapper, id, &desc2), + DirectWrapper::defineProperty(cx, wrapper, id, &desc2), NOTHING); } bool CrossCompartmentWrapper::getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props) { PIERCE(cx, wrapper, GET, NOTHING, - Wrapper::getOwnPropertyNames(cx, wrapper, props), + DirectWrapper::getOwnPropertyNames(cx, wrapper, props), call.origin->wrap(cx, props)); } bool CrossCompartmentWrapper::delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) { PIERCE(cx, wrapper, SET, call.destination->wrapId(cx, &id), - Wrapper::delete_(cx, wrapper, id, bp), + DirectWrapper::delete_(cx, wrapper, id, bp), NOTHING); } bool CrossCompartmentWrapper::enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props) { PIERCE(cx, wrapper, GET, NOTHING, - Wrapper::enumerate(cx, wrapper, props), + DirectWrapper::enumerate(cx, wrapper, props), call.origin->wrap(cx, props)); } bool CrossCompartmentWrapper::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) { PIERCE(cx, wrapper, GET, call.destination->wrapId(cx, &id), - Wrapper::has(cx, wrapper, id, bp), + DirectWrapper::has(cx, wrapper, id, bp), NOTHING); } bool CrossCompartmentWrapper::hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) { PIERCE(cx, wrapper, GET, call.destination->wrapId(cx, &id), - Wrapper::hasOwn(cx, wrapper, id, bp), + DirectWrapper::hasOwn(cx, wrapper, id, bp), NOTHING); } bool CrossCompartmentWrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) { PIERCE(cx, wrapper, GET, call.destination->wrap(cx, &receiver) && call.destination->wrapId(cx, &id), - Wrapper::get(cx, wrapper, receiver, id, vp), + DirectWrapper::get(cx, wrapper, receiver, id, vp), call.origin->wrap(cx, vp)); } bool CrossCompartmentWrapper::set(JSContext *cx, JSObject *wrapper_, JSObject *receiver_, jsid id_, bool strict, Value *vp) { RootedVarObject wrapper(cx, wrapper_), receiver(cx, receiver_); RootedVarId id(cx, id_); RootedVarValue value(cx, *vp); PIERCE(cx, wrapper, SET, call.destination->wrap(cx, receiver.address()) && call.destination->wrapId(cx, id.address()) && call.destination->wrap(cx, value.address()), - Wrapper::set(cx, wrapper, receiver, id, strict, value.address()), + DirectWrapper::set(cx, wrapper, receiver, id, strict, value.address()), NOTHING); } bool CrossCompartmentWrapper::keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) { PIERCE(cx, wrapper, GET, NOTHING, - Wrapper::keys(cx, wrapper, props), + DirectWrapper::keys(cx, wrapper, props), call.origin->wrap(cx, props)); } /* * We can reify non-escaping iterator objects instead of having to wrap them. This * allows fast iteration over objects across a compartment boundary. */ static bool @@ -621,17 +622,17 @@ Reify(JSContext *cx, JSCompartment *orig return VectorToValueIterator(cx, obj, ni->flags, keys, vp); } bool CrossCompartmentWrapper::iterate(JSContext *cx, JSObject *wrapper, unsigned flags, Value *vp) { PIERCE(cx, wrapper, GET, NOTHING, - Wrapper::iterate(cx, wrapper, flags, vp), + DirectWrapper::iterate(cx, wrapper, flags, vp), CanReify(vp) ? Reify(cx, call.origin, vp) : call.origin->wrap(cx, vp)); } bool CrossCompartmentWrapper::call(JSContext *cx, JSObject *wrapper_, unsigned argc, Value *vp) { RootedVarObject wrapper(cx, wrapper_); @@ -642,17 +643,17 @@ CrossCompartmentWrapper::call(JSContext vp[0] = ObjectValue(*call.target); if (!call.destination->wrap(cx, &vp[1])) return false; Value *argv = JS_ARGV(cx, vp); for (size_t n = 0; n < argc; ++n) { if (!call.destination->wrap(cx, &argv[n])) return false; } - if (!Wrapper::call(cx, wrapper, argc, vp)) + if (!DirectWrapper::call(cx, wrapper, argc, vp)) return false; call.leave(); return call.origin->wrap(cx, vp); } bool CrossCompartmentWrapper::construct(JSContext *cx, JSObject *wrapper_, unsigned argc, Value *argv, @@ -663,17 +664,17 @@ CrossCompartmentWrapper::construct(JSCon AutoCompartment call(cx, wrappedObject(wrapper)); if (!call.enter()) return false; for (size_t n = 0; n < argc; ++n) { if (!call.destination->wrap(cx, &argv[n])) return false; } - if (!Wrapper::construct(cx, wrapper, argc, argv, rval)) + if (!DirectWrapper::construct(cx, wrapper, argc, argv, rval)) return false; call.leave(); return call.origin->wrap(cx, rval); } extern JSBool js_generic_native_method_dispatcher(JSContext *cx, unsigned argc, Value *vp); @@ -700,17 +701,17 @@ CrossCompartmentWrapper::nativeCall(JSCo Value *srcend = srcArgs.array() + srcArgs.length(); Value *dst = dstArgs.base(); for (; src != srcend; ++src, ++dst) { *dst = *src; if (!call.destination->wrap(cx, dst)) return false; } - if (!Wrapper::nativeCall(cx, wrapper, clasp, native, dstArgs)) + if (!DirectWrapper::nativeCall(cx, wrapper, clasp, native, dstArgs)) return false; srcArgs.rval() = dstArgs.rval(); dstArgs.pop(); call.leave(); return call.origin->wrap(cx, &srcArgs.rval()); } @@ -719,44 +720,44 @@ CrossCompartmentWrapper::hasInstance(JSC { AutoCompartment call(cx, wrappedObject(wrapper)); if (!call.enter()) return false; Value v = *vp; if (!call.destination->wrap(cx, &v)) return false; - return Wrapper::hasInstance(cx, wrapper, &v, bp); + return DirectWrapper::hasInstance(cx, wrapper, &v, bp); } JSString * CrossCompartmentWrapper::obj_toString(JSContext *cx, JSObject *wrapper) { AutoCompartment call(cx, wrappedObject(wrapper)); if (!call.enter()) return NULL; - JSString *str = Wrapper::obj_toString(cx, wrapper); + JSString *str = DirectWrapper::obj_toString(cx, wrapper); if (!str) return NULL; call.leave(); if (!call.origin->wrap(cx, &str)) return NULL; return str; } JSString * CrossCompartmentWrapper::fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) { AutoCompartment call(cx, wrappedObject(wrapper)); if (!call.enter()) return NULL; - JSString *str = Wrapper::fun_toString(cx, wrapper, indent); + JSString *str = DirectWrapper::fun_toString(cx, wrapper, indent); if (!str) return NULL; call.leave(); if (!call.origin->wrap(cx, &str)) return NULL; return str; } @@ -826,17 +827,17 @@ SecurityWrapper::objectClassIs(JSO template bool SecurityWrapper::regexp_toShared(JSContext *cx, JSObject *obj, RegExpGuard *g) { return Base::regexp_toShared(cx, obj, g); } -template class js::SecurityWrapper; +template class js::SecurityWrapper; template class js::SecurityWrapper; class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler { private: static int sDeadObjectFamily; public: diff -r 981eaf7b3333 js/src/jswrapper.h --- a/js/src/jswrapper.h Tue May 22 21:42:21 2012 +0200 +++ b/js/src/jswrapper.h Tue May 29 23:55:40 2012 +0200 @@ -73,24 +73,24 @@ class JS_FRIEND_API(AbstractWrapper) : p virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp); virtual void leave(JSContext *cx, JSObject *wrapper); static JSObject *wrappedObject(const JSObject *wrapper); static AbstractWrapper *wrapperHandler(const JSObject *wrapper); }; /* No-op wrapper handler base class. */ -class JS_FRIEND_API(Wrapper) : public AbstractWrapper +class JS_FRIEND_API(DirectWrapper) : public AbstractWrapper { public: - explicit Wrapper(unsigned flags); + explicit DirectWrapper(unsigned flags); typedef enum { PermitObjectAccess, PermitPropertyAccess, DenyAccess } Permission; - virtual ~Wrapper(); + virtual ~DirectWrapper(); /* ES5 Harmony derived wrapper traps. */ virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE; virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE; virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) MOZ_OVERRIDE; virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict, Value *vp) MOZ_OVERRIDE; virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE; @@ -101,34 +101,40 @@ class JS_FRIEND_API(Wrapper) : public Ab virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *rval) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE; virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE; virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE; virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) MOZ_OVERRIDE; using AbstractWrapper::Action; - static Wrapper singleton; + static DirectWrapper singleton; static JSObject *New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, - Wrapper *handler); + DirectWrapper *handler); using AbstractWrapper::wrappedObject; using AbstractWrapper::wrapperHandler; enum { CROSS_COMPARTMENT = 1 << 0, LAST_USED_FLAG = CROSS_COMPARTMENT }; static void *getWrapperFamily(); }; +/* + * This typedef is only here to avoid code churn in xpconnect. It will be + * removed as soon as the Wrapper base class lands. + */ +typedef DirectWrapper Wrapper; + /* Base class for all cross compartment wrapper handlers. */ -class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper +class JS_FRIEND_API(CrossCompartmentWrapper) : public DirectWrapper { public: CrossCompartmentWrapper(unsigned flags); virtual ~CrossCompartmentWrapper(); /* ES5 Harmony fundamental wrapper traps. */ virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, @@ -179,17 +185,17 @@ class JS_FRIEND_API(SecurityWrapper) : p public: SecurityWrapper(unsigned flags); virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE; virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE; virtual bool regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g) MOZ_OVERRIDE; }; -typedef SecurityWrapper SameCompartmentSecurityWrapper; +typedef SecurityWrapper SameCompartmentSecurityWrapper; typedef SecurityWrapper CrossCompartmentSecurityWrapper; /* * A hacky class that lets a friend force a fake frame. We must already be * in the compartment of |target| when we enter the forced frame. */ class JS_FRIEND_API(ForceFrame) {